1、事務管理是應用系統開發中必不可少的一部分。在spring boot 中,使用事務非常簡單,只要直接在方法上面加入@Transactional 就可以實現。
2、SpringBoot項目會自動配置一個 DataSourceTransactionManager,所以我們只需在方法(或者類)加上 @Transactional 注解,就自動納入 Spring 的事務管理了。
如下在方法加上 @Transactional 注解:
@Transactional
public void insertUser() {
User user = new User("張三");
userMapper.insertOneUser(user); //向數據庫插入一條記錄
throw new RuntimeException("發生異常"); //手動模擬拋出異常
}
拋出異常之后,事務會自動回滾,數據不會插入到數據庫。
- 當Transaction內發生unchecked exception的時候,會自動rollback,但是當Transaction內發生checked exception時,是不會自動rollback的。
- 如果使用try-catch捕獲異常,則該事務不會回滾。
3、默認spring事務只在發生未被捕獲的 RuntimeException 時才回滾。
spring aop異常捕獲原理:被攔截的方法需顯式拋出異常,並不能經任何處理,這樣aop代理才能捕獲到方法的異常,才能進行回滾,默認情況下aop只捕獲RuntimeException的異常,但可以通過配置來捕獲特定的異常並回滾。
換句話說在service的方法中不使用try catch或者在catch中最后加上throw new runtimeexcetpion(),這樣程序異常時才能被aop捕獲進而回滾。
解決方案:
-
方案1.例如service層處理事務,那么service中的方法中不做異常捕獲,或者在catch語句中最后增加throw new RuntimeException()語句,以便讓aop捕獲異常再去回滾,並且在service上層(webservice客戶端,view層action)要繼續捕獲這個異常並處理。
-
方案2.在service層方法的catch語句中增加:TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();語句,手動回滾,這樣上層就無需去處理異常。
例如
catch (Exception e)
{
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//手動回滾
result.put("status", 0);
result.put("msg",msg);
return result;
}