Spring事务


一、Spring事务简介

  1. 事务作用:在数据层保障一系列的数据库操作同成功同失败

  2. Spring事务作用:在数据层或业务层保障一系列的数据库操作同成功同失败

  3. 实现:

    通过PlatformTransactionManager接口实现:

    public interface PlatformTransactionManager{
        void commit(TransactionStatus status)throws TransactionException;
        void rollback(TransactionStatus status)throws TransactionException;
    )
    

二、案例

1. 模拟银行账户间转账业务

  1. 需求:实现任意两个账户间转账操作(A账户减钱,B账户加钱)

  2. 分析:

    1. 数据层提供基础操作,指定账户减钱(outMoney),指定账户加钱(inMoney)
    2. 业务层提供转账操作(transfer),调用减钱加钱的操作
    3. 提供2个账号和操作金额执行转账操作
    4. 基于Spring整合MyBatis环境搭建上述操作
  3. 代码:

    业务层接口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);
    };
    
  4. 结果分析:

    • 程序正常执行时,账户金额A减B加,没有问题
    • 程序出现异常后,转账失败,但是异常之前操作成功,异常之后操作失败,整体业务失败
  5. 开启事务:

    1. Spring配置类中使用@EnableTransactionManagement注解开启事务管理

    2. 在JdbcConfig中设置事务管理器:

      @Bean
      public PlatformTransactionManager transactionManager(DataSource dataSource) {
          DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
          transactionManager.setDataSource(dataSource);
          return transactionManager;
      };
      
    3. 业务层接口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);
    };
    
  • 行为:


文章作者: Cikian
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Cikian !
评论
  目录