Spring编程式事务实现方式和注意点

Spring事务使用有两种方式:声明式事务(如通过@Transactional实现注解方式或者xml配置方式)和编程式事务方式,优缺点如下:

  •   声明式事务:通过注解和xml配置使开发者只关注业务开发,而不需要关注事务的提交和回滚,但最小粒度在方法上,不能对一块代码增加事务,另外也要考虑事务嵌套带来的副作用(比如长事务)。
  •  编程式事务:比较灵活,需要开发者在代码中手动的管理事务的开启、提交、回滚等操作,但若对事务理解不够深刻,容易出错。

这里重点讲编程式事务方式使用的案例和注意点,使用方式如下:

  private void executeTransactional(HelpParticipationContextDTO contextDTO) {
        return transactionTemplate.execute(action ->  {
            // 1.插入用户信息
            int row = insertStudent();
            if(row <= 0) {
               throw new RuntimeException("插入失败");
            }
            // 2.更新统计信息
            updateStatistics(contextDTO);
            return true;
        });
    }


 默认场景下若业务处理过程中出现RuntimeException或者Error异常就会回滚,详细参考org.springframework.transaction.support.TransactionTemplate-execute方法实现,还有一种实现方式如下:

private void executeTransactional(HelpParticipationContextDTO contextDTO) {
        return transactionTemplate.execute(action ->  {
          try {
            // 1.插入用户信息
            int row = insertStudent();
            if(row <= 0) {
               throw new RuntimeException("插入失败");
            }
            // 2.更新统计信息
            updateStatistics(contextDTO);
            return true;
          } catch (Exception e) {
           TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            // status.setRollbackOnly();
            return false;
          }
        });
    }

这种方式只是把当前事务标记为回滚,当事务进行提交时发现该事务已经设置了回滚标记,则对当前事务进行回滚,这里要看提交事务的源代码,如下:

// org.springframework.transaction.support.AbstractPlatformTransactionManager-commit
    public final void commit(TransactionStatus status) throws TransactionException {
        if (status.isCompleted()) {
            throw new IllegalTransactionStateException(
                    "Transaction is already completed - do not call commit or rollback more than once per transaction");
        }

        DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;
        // 这里就会判断事务的回滚标记
        if (defStatus.isLocalRollbackOnly()) {
            if (defStatus.isDebug()) {
                logger.debug("Transactional code has requested rollback");
            }
            processRollback(defStatus, false);
            return;
        }

        if (!shouldCommitOnGlobalRollbackOnly() && defStatus.isGlobalRollbackOnly()) {
            if (defStatus.isDebug()) {
                logger.debug("Global transaction is marked as rollback-only but transactional code requested commit");
            }
            processRollback(defStatus, true);
            return;
        }

        processCommit(defStatus);
    }    

总结一下,当业务出现了RuntimeException或者Error异常,Spring事务进行回滚,另外编程式事务对代码控制比较灵活,但是建立在对Spring事务原理理解的基础上(上面总结了编程式事务使用的两种方式)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bboyzqh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值