1. 程式人生 > >spring 聲明式事務中try catch捕獲異常

spring 聲明式事務中try catch捕獲異常

調用 color exception 代碼 狀態 新的 for 自定義 這樣的

原文:http://heroliuxun.iteye.com/blog/848122

今天遇到了一個這個問題

最近遇到這樣的問題,使用spring時,在業務層需要捕獲異常(特殊需要),當前一般情況下不需要這樣做的。具體如下: 在ServiceA類中有method1,在該方法中調用另一個ServiceB類的method2方法時(假定該方法拋出異常),method1方法捕獲該異常但是沒有向上拋出。spring提示:org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only

原因是 先插入數據,然後調用另外一個service 加入事務 另外一個事務報錯了,會拋這個異常 Transaction rolled back because it has been marked as rollback-only

類似於你再get方法裏面操作數據(非只讀)的錯

業務場景: 在一個service裏面先操作(增刪改)數據之後,然後調用另外一個service(另外一個業務),而另外一個service拋異常,在你try catch這個業務的時候,spring默認會報 Transaction rolled back because it has been marked as rollback-only

@Transactional(rollbackFor = Throwable.class)//默認事務傳播方式required 
public Class ServiceA { 
    
    @Autowired  
    private Dao dao; 

    @Autowired  
    private ServiceB serviceB;  // 註入另一Service Bean 
    
    public void method1() { 

        dao.insert(vo);  // 保存ServiceA的vo對象 
        try { 
            serviceB.method2(vo); // 保存ServiceB的vo對象 
        } catch (CustomException e) { 
            // 捕獲自定義異常,但是沒有向上拋出 
        } 

    } 
} 


以下是ServiceB的示例代碼 
@Transactional(rollbackFor = Throwable.class)//默認事務傳播方式required 
public Class ServiceB { 
    
    @Autowired  
    private Dao dao; 
    
    public void method2() throws CustomException { 

        dao.insert(vo);  // 保存ServiceA的vo對象 
    } 
} 

  出現以上原因是spring執行method1方法時,開啟一個新的事物,當調用method2方法時,當method2方法加入到method1方法的當前事務,當method2拋出異常,spring標記事務為回滾狀態,method1方法捕獲該異常,但沒有拋出,spring會提交method1的事務,但spring發現該事務已經標記為回滾狀態,而代碼中卻要提交事務,所以才會拋出以上的異常。 解決的方法:在ServiceB的method2方法上註解,告訴spring當該方法拋出自定義異常CustomException時,不要回滾事務,這樣當該方法拋出異常時,spring不會標記事務為回滾狀態。

 @Transactional(noRollbackFor=CustomException.class)  public void method2() throws CustomException{  
}

感謝原文的博客

spring 聲明式事務中try catch捕獲異常