zoukankan      html  css  js  c++  java
  • 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。

  • 相关阅读:
    Python开发环境Spyder介绍
    Python干货整理之数据结构篇
    通过Python爬虫按关键词抓取相关的新闻
    疫情后来场说走就走的旅行,Python制作一份可视化的旅行攻略
    详细介绍去一年在 PyPI 上下载次数最多的 Python 包
    Python错误与异常
    python爬虫爬取2020年中国大学排名
    微信史上最短的一行功能代码:拍一拍
    Python爬取某宝商品数据案例:100页的价格、购买人数等数据
    我的SAS菜鸟之路7
  • 原文地址:https://www.cnblogs.com/super-chao/p/15169923.html
Copyright © 2011-2022 走看看