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。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM