一、Spring事务简介
事务作用:在数据层保障一系列的数据库操作同成功同失败
Spring事务作用:在数据层或业务层保障一系列的数据库操作同成功同失败
实现:
通过PlatformTransactionManager接口实现:
public interface PlatformTransactionManager{ void commit(TransactionStatus status)throws TransactionException; void rollback(TransactionStatus status)throws TransactionException; )
二、案例
1. 模拟银行账户间转账业务
需求:实现任意两个账户间转账操作(A账户减钱,B账户加钱)
分析:
- 数据层提供基础操作,指定账户减钱(outMoney),指定账户加钱(inMoney)
- 业务层提供转账操作(transfer),调用减钱加钱的操作
- 提供2个账号和操作金额执行转账操作
- 基于Spring整合MyBatis环境搭建上述操作
代码:
业务层接口AccountService:
public interface AccountService { void transfer(String out, String in, Double money); };
AccountService接口实现类:
@Service public class AccountServiceImpl implements AccountService { @Autowired private AccountDao accountDao; @Override public void transfer(String out, String in, Double money) { accountDao.outMoney(out, money); accountDao.inMoney(in, money); }; };
数据层接口AccountDao:
public interface AccountDao { @Update("update tb_account set money=money+#{money}; where name=#{name};") void inMoney(@Param("name") String name, @Param("money") Double money); @Update("update tb_account set money=money-#{money}; where name=#{name};") void outMoney(@Param("name") String name, @Param("money") Double money); };
测试用例:
@Test public void testTran() { accountService.transfer("Mike", "Tom", 100d); };
结果分析:
- 程序正常执行时,账户金额A减B加,没有问题
- 程序出现异常后,转账失败,但是异常之前操作成功,异常之后操作失败,整体业务失败
开启事务:
Spring配置类中使用
@EnableTransactionManagement
注解开启事务管理在JdbcConfig中设置事务管理器:
@Bean public PlatformTransactionManager transactionManager(DataSource dataSource) { DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(); transactionManager.setDataSource(dataSource); return transactionManager; };
业务层接口AccountService修改:
public interface AccountService { @Transactional void transfer(String out, String in, Double money); };
在要开启事务的方法上方使用
@Transactional
注解开启事务- Spring注解式事务通常添加在业务层接口中而不会添加到业务层实现类中,降低耦合
- 注解式事务可以添加到业务方法上表示当前方法开启事务,也可以添加到接口上表示当前接口所有方法开启事务
三、Spring事务角色
- 事务管理员:发起事务方,在Spring中通常指代业务层开启事务的方法
- 事务协调员:加入事务方,在Spring中通常指代数据层方法,也可以是业务层方法
四、事务相关配置
属性 | 作用 | 类型 | 示例 |
---|---|---|---|
value |
设置事务管理器(可选) | String |
value = "txManager" |
propagation |
设置事务传播行为(可选) | enum: Propagation |
propagation = Propagation.REQUIRES_NEW |
isolation |
设置事务隔离级别(可选) | enum: Isolation |
isolation = REPEATABLE_READ |
readOnly |
设置是否为只读事务 | boolean |
readOnly=true 只读事务 |
timeout |
设置事务超时时间 | int (秒) |
time = -1 永不超时 |
rollbackFor |
设置事务回滚的异常类数组 | Class 对象数组,必须继承自Throwable |
rollbackFor = {IOException.class} |
rollbackForClassName |
设置事务回滚的异常类名字数组(String) | 类名数组,必须继承自Throwable |
rollbackForClassName = {IOException} |
noRollbackFor |
设置事务不回滚的异常类数组(class) | Class 对象数组,必须继承自Throwable |
noRollbackFor = {IOException.class} |
noRollbackForClassName |
设置事务不回滚的异常类名字数组(String) | 类名数组,必须继承自Throwable |
noRollbackForClassName = {IOException} |
五、事务传播行为
事务传播行为:事务协调员对事务管理员所携带事务的处理办法
e.g. 在业务层接口上添加Spring事务,设置事务传播行为REQUIRES_NEW(需要新事务):
public interface LogService { @Transactional(propagation = Propagation.REQUIRES_NEW) void log(String out, String in, Double money); };
行为: