[一知半解,就是给自己挖坑]
本文,我们来介绍一下Spring中的事务管理,在基础片中,我们直接介绍基本概念及用法,更多内容将会在高级篇中叙述,敬请期待!
-------------------------------------------------------------------------------------------------------------------------------------
1.什么是事务?
这里的事务的概念,最好在计算机环境下来理解。在操作系统中,我们为了保证一段程序执行过程不被中断,而引入了互斥锁的概念。这里事务的概念可以看作是对于互斥锁的事件过程的另一种解释。即,一个事务执行的前后,数据资源的状态始终是正确的。由此,我们得到了事务的几个基本属性:原子性,一致性,隔离性,持久性。
1.1.原子性:
原子性要求事务所包含的全部操作是一个不可分割的整体,这些操作要么全部提交成功,要么只要其中一个操作失败,那么全部失败。
1.2.一致性:
一致性要求事务再执行之前数据资源是保持一致的,在执行之后数据资源仍然保持一致。举个例子来理解:A,B两个变量之和是10为大前提,那个对其中一个变量改变值之后的结果,必须也要满足这个大前提。生活中常见的例子是银行里的转账操作就是一致性的非常好的例子。
1.3.隔离性:
隔离性即规定了不同事务之间的相互影响程度,换句话说就是不同事务之间的执行时机。这里的隔离性就衍生出原子性,一致性的概念。当一个事务开始执行对数据资源的访问时,另一个事务合适能够访问数据资源就决定了隔离性的大小。这里分为4个级别,由宽松到严格的顺序为:“Read Uncommitted”,“Read Committed”,“Repeatable Read”和“Serializable”关于这4个的概念,请读者自行查阅相关资料学习。
1.4.持久性
持久性要求事务对于数据资源的操作不可逆转,即事务完成之后,程序执行流已经彻底的退出该事务,该事务对应的程序执行流不可回退。通俗点的讲,就是“不要赖账”
-------------------------------------------------------------------------------------------------------------------------------------
接下来,我们就来看看Spring中的事务管理的使用。
本文我们先来介绍Spring中的第一种方式:使用“编程式事务管理”的实现方法
准备工作:
a.操作系统:win7 x64
b.开发工具:eclipse mars j2ee版本,maven3.3.2,Spring 4,junit4.12,mybatis
c.建立Spring10,工程基本结构如下图:
-------------------------------------------------------------------------------------------------------------------------------------
1.创建BankDao.java。具体内容如下:
-
package com.java.ingo.dao;
-
import com.java.ingo.entity.Account;
-
/**
-
*@author 作者 E-mail:ingo
-
*@version 创建时间:2016年3月6日上午9:21:05
-
*类说明
-
*/
-
public interface BankDao {
-
public void update(Account account);
-
}
2.创建Account.java文件,具体内容如下:
-
package com.java.ingo.entity;
-
/**
-
*@author 作者 E-mail:ingo
-
*@version 创建时间:2016年3月6日上午10:36:57
-
*类说明
-
*/
-
public class Account {
-
private int id;
-
private int money;
-
public int getId() {
-
return id;
-
}
-
public void setId(int id) {
-
this.id = id;
-
}
-
public int getMoney() {
-
return money;
-
}
-
public void setMoney(int money) {
-
this.money = money;
-
}
-
public Account(int id, int money) {
-
super();
-
this.id = id;
-
this.money = money;
-
}
-
public Account() {
-
super();
-
// TODO Auto-generated constructor stub
-
}
-
}
3.创建IBankService.java文件,具体内容如下:
-
package com.java.ingo.service;
-
/**
-
*@author 作者 E-mail:ingo
-
*@version 创建时间:2016年3月6日上午9:26:22
-
*类说明
-
*/
-
public interface IBankService {
-
public void transferMoney(int sourceId,int desId,int money);
-
}
4.创建BankServiceImpl.java文件,具体内容如下:
-
package com.java.ingo.service.impl;
-
import org.springframework.beans.factory.annotation.Autowired;
-
import org.springframework.stereotype.Component;
-
import org.springframework.stereotype.Service;
-
import org.springframework.transaction.TransactionStatus;
-
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
-
import org.springframework.transaction.support.TransactionTemplate;
-
import com.java.ingo.dao.BankDao;
-
import com.java.ingo.entity.Account;
-
import com.java.ingo.service.IBankService;
-
/**
-
*@author 作者 E-mail:ingo
-
*@version 创建时间:2016年3月6日上午9:26:22
-
*类说明
-
*/
-
@Service
-
public class BankServiceImpl implements IBankService{
-
@Autowired
-
private BankDao bankDao;
-
private TransactionTemplate transactionTemplate;
-
public void setBankDao(BankDao bankDao) {
-
this.bankDao = bankDao;
-
}
-
public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
-
this.transactionTemplate = transactionTemplate;
-
}
-
public void transferMoney(final int countA,final int countB,final int money) {
-
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
-
@Override
-
protected void doInTransactionWithoutResult(TransactionStatus status) {
-
Account accountA = new Account(countA,money);
-
Account accountB = new Account(countB,money);
-
bankDao.updateOut(accountA);
-
//System.out.println(1/0);
-
bankDao.updateIn(accountB);
-
}
-
});
-
}
-
}
5.创建beans.xml文件,具体内容如下;
-
<?xml version="1.0" encoding="UTF-8"?>
-
<beans xmlns="http://www.springframework.org/schema/beans"
-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-
xmlns:p="http://www.springframework.org/schema/p"
-
xmlns:aop="http://www.springframework.org/schema/aop"
-
xmlns:context="http://www.springframework.org/schema/context"
-
xmlns:jee="http://www.springframework.org/schema/jee"
-
xmlns:tx="http://www.springframework.org/schema/tx"
-
xsi:schemaLocation="
-
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
-
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
-
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
-
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd
-
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
-
<context:component-scan base-package="com.java" />
-
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
-
destroy-method="close">
-
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
-
<property name="url" value="jdbc:mysql://localhost:3306/db_bank" />
-
<property name="username" value="root" />
-
<property name="password" value="1234" />
-
</bean>
-
<!-- 配置mybatis的sqlSessionFactory -->
-
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
-
<property name="dataSource" ref="dataSource" />
-
<!-- 自动扫描mappers.xml文件 -->
-
<property name="mapperLocations" value="classpath:mappers/*.xml"></property>
-
</bean>
-
<!-- DAO接口所在包名,Spring会自动查找其下的类 -->
-
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
-
<property name="basePackage" value="com.java.ingo.dao" />
-
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
-
</bean>
-
<!-- jdbc事务管理器 -->
-
<bean id="transactionManager"
-
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
-
<property name="dataSource" ref="dataSource"></property>
-
</bean>
-
<bean id="transactionTemplate"
-
class="org.springframework.transaction.support.TransactionTemplate">
-
<constructor-arg
-
type="org.springframework.transaction.PlatformTransactionManager"
-
ref="transactionManager" />
-
</bean>
-
<bean id="namedParameterJdbcTemplate"
-
class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
-
<constructor-arg ref="dataSource"></constructor-arg>
-
</bean>
-
<bean id="bankService" class="com.java.ingo.service.impl.BankServiceImpl">
-
<property name="transactionTemplate" ref="transactionTemplate"></property>
-
</bean>
-
</beans>
6.创建BankMapper.xml文件,具体内容如下:
-
<?xml version="1.0" encoding="UTF-8"?>
-
<!DOCTYPE mapper
-
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
-
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-
<mapper namespace="com.java.ingo.dao.BankDao">
-
<update id="updateIn" parameterType="com.java.ingo.entity.Account">
-
UPDATE account SET money=money+#{money} WHERE id=#{id}
-
</update>
-
<update id="updateOut" parameterType="com.java.ingo.entity.Account">
-
UPDATE account SET money=money-#{money} WHERE id=#{id}
-
</update>
-
</mapper>
7.创建T.java文件,具体内容如下:
-
package Main;
-
import org.springframework.context.ApplicationContext;
-
import org.springframework.context.support.ClassPathXmlApplicationContext;
-
import com.java.ingo.service.IBankService;
-
/**
-
* @author 作者 E-mail:ingo
-
* @version 创建时间:2016年3月4日上午11:46:52 类说明
-
*/
-
public class T {
-
public static void main(String[] args) {
-
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:beans.xml");
-
IBankService bankService = (IBankService) context.getBean("bankService");
-
bankService.transferMoney(1,2,200);
-
}
-
}
8.创建数据库db_bank,创建t_account表。
9.测试方法:运行main方法,然后刷新数据库,观察数据库变化。
10.打开System.out.println(1/0);注释,再次运行main方法,观察数据库变化。
-----------------------------------------------------------------------------------------------------------------------------------
至此,白话Spring(基础篇)---编程式事务(1)结束。
参考资料:
Spring官网:http://spring.io/docs
Mybatis官方文档:官方文档