spring 聲明式事務中try catch捕獲異常
原文: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捕獲異常