你的Spring事務為什麼不會自動回滾?
Spring的事務傳播行為有七種,當前我說的是預設的那種。我們知道Spring的宣告式事務是基於AOP的,那麼就是AOP玩的又是代理物件,那你是不是就知道了,這個事務的大概實現原理了。。。
首先我們要明確RuntimeException與Exception之間的關係與他們分別的含義:
1.在Java中異常的基類為Throwable,他有兩個子類Exception與Errors,同時RuntimeException就是Exception的子類;
2.RuntimeException,即執行時異常,為非受檢(UNCHECKED)異常;
3.Exception的其他子類異常,為非執行時異常,為受檢
Spring事務回滾機制是這樣的:當所攔截的方法有指定異常丟擲,事務才會自動進行回滾!
①被攔截方法-—— 註解式:方法或者方法所在類被@Transactional註解;
②異常—— 該方法的執行過程必須出現異常,這樣事務管理器才能被觸發,並對此做出處理;
③指定異常—— 預設配置下,事務只會對Error與RuntimeException及其子類這些UNChecked異常,做出回滾。一般的Exception這些Checked異常不會發生回滾(如果一般Exception想回滾要做出配置);
RuntimeException所包含的子類具體有哪些:
下面給出一些受檢CHECKED異常:
提醒:執行方法的時候出現了SQL執行的Exception事務還是發生了回滾,是因為Spring框架下,所有SQL異常都被org.springframework重寫為RuntimeException!
還有一點當這個方法上加了@Transaction(此處是預設的傳播行為)註解,當這個方法丟擲RuntimeException之後被try catch之後宣告式事務是不會感知的,當然也不會回滾,但是當在另一個也有事務的方法內呼叫了這個方法,形成巢狀事務,這個方法丟擲了RuntimeException之後在上層方法內try catch的話,則上層方法的整個事務會被回滾。