Transaction rolled back because it has been marked as rollback-only原因及解决办法

异常:Transaction rolled back because it has been marked as rollback-only

原因:已经标记为rollback-only,但是后面的程序执行后又commit事务,抛出此异常。虽然都回滚,不影响正常业务。但是日志打印这种异常让人很难受。

解决办法:(核心思想:既然标识为rollback-only,就不要让事务再commit)

1.service不try catch。controller中try catch。异常会被层层感知,不会让事务commit。

@Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public void addTest(){
        testDao.addTest();
        int i = 1/0;
//        try {
//            testDao.addTest();
//            int i = 1/0;
//            return "success";
//        }catch (Exception e){
//            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
//            throw new RuntimeException();
//            //return "exception";
//        }
    }

2.service中try catch后,throw new RuntimeException();。让调用方感知异常,不会让事务commit。

@Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public String addTest(){
        try {
            testDao.addTest();
            int i = 1/0;
            return "success";
        }catch (Exception e){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            throw new RuntimeException();
            //return "exception";
        }
    }

3.service中try catch后,手动回滚异常,并返回异常码。外层判断调用service结果,是否再手动回滚。虽然感知不到异常,但是通过判断调用方返回结果,是否手动回滚。不会让事务commit。 

@Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public void addUser(){
        try {
            userDao.addUser();
            String logResult = logService.addLog();
            if("exception".equals(logResult)){
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return;
            }
            String testResult = testService.addTest();
            if("exception".equals(testResult)){
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return;
            }
        } catch (Exception e){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        System.out.println("end");
    }

 

虽然报错Transaction rolled back because it has been marked as rollback-only并不影响业务的正常逻辑。因为即使报这个异常,也会整体回滚。

但是为了解决这个问题。有一个核心思想就是:不要让同一个事务标记为rollback-only后又commit。

以上三种方案都是防止事务标记为rollback-only后又commit。

 

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值