一、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); } -
行为:

评论