原文: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{ }
感謝原文的博客
