原文:http://heroliuxun.iteye.com/blog/848122 java
今天遇到了一個這個問題spring
最近遇到這樣的問題,使用spring時,在業務層須要捕獲異常(特殊須要),當前通常狀況下不須要這樣作的。具體以下: 在ServiceA類中有method1,在該方法中調用另外一個ServiceB類的method2方法時(假定該方法拋出異常),method1方法捕獲該異常可是沒有向上拋出。spring提示:org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-onlyui
緣由是 先插入數據,而後調用另一個service 加入事務 另一個事務報錯了,會拋這個異常 Transaction rolled back because it has been marked as rollback-onlyspa
相似於你再get方法裏面操做數據(非只讀)的錯code
業務場景: 在一個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不會標記事務爲回滾狀態。 blog
@Transactional(noRollbackFor=CustomException.class) public void method2() throws CustomException{ }
感謝原文的博客事務