Spring中的事務隔離級別和傳播行為
Spring的事務隔離級別和事務的傳播行為是面試中經??疾斓膯栴},做個簡單的總結。
傳播行為
在SpringBoot中通過Transactional的propagation屬性來指定,Transactional注解的具體源碼如下所示
public @interface Transactional { @AliasFor("transactionManager") String value() default ""; @AliasFor("value") String transactionManager() default ""; Propagation propagation() default Propagation.REQUIRED; Isolation isolation() default Isolation.DEFAULT; }
可以看出,默認的值是Propagation.REQUIRED;
其他的還有:
- 1>
PROPAGATION_REQUIRED
支持當前事務,假設當前沒有事務。就新建一個事務。 - 2>
PROPAGATION_SUPPORTS
支持當前事務,假設當前沒有事務,就以非事務方式運行。 - 3>
PROPAGATION_MANDATORY
支持當前事務,假設當前沒有事務,就拋出異常。 - 4>
PROPAGATION_REQUIRES_NEW
新建事務,假設當前存在事務。把當前事務掛起。 - 5>
PROPAGATION_NOT_SUPPORTED
以非事務方式運行操作。假設當前存在事務,就把當前事務掛起。 - 6>
PROPAGATION_NEVER
以非事務方式運行,假設當前存在事務,則拋出異常。 - 7>
PROPAGATION_NESTED
如果當前存在事務,則在嵌套事務內執(zhí)行。如果當前沒有事務,則進行與PROPAGATION_REQUIRED類似的操作。
舉個例子進行說明
ServiceA { void methodA() { ServiceB.methodB(); } } ServiceB { void methodB() { } }
1>PROPAGATION_REQUIRED
如果當前執(zhí)行的事務不在另外一個事務里,就新起一個事務;ServiceB和 ServiceA在同一個事務里面,ServiceB如果異常,則整個事務認為是執(zhí)行失敗的,即便是在A里面try catch了異常也會導致A和B都回滾;同樣,即便B執(zhí)行成功,A執(zhí)行報錯產生異常,那么A和B都會回滾的;
2>PROPAGATION_SUPPORTS
假設當前在事務中。即以事務的形式執(zhí)行。假設當前不再一個事務中,那么就以非事務的形式執(zhí)行;
3>PROPAGATION_MANDATORY
支持當前事務,假設當前沒有事務,就拋出異常,也就是說他必須在一個父事務中去執(zhí)行;否則就會拋出異常;
4>PROPAGATION_REQUIRES_NEW
新建事務,假設當前存在事務,把當前事務掛起;比如服務A的事務級別是PROPAGATION_REQUIRED,那么服務B的級別是PROPAGATION_REQUIRES_NEW;那么當運行到ServiceB.methodB的時候,ServiceA.methodA所在的事務就會掛起。
ServiceB.methodB會起一個新的事務,等待ServiceB.methodB的事務完畢以后,他才繼續(xù)運行;跟PROPAGATION_REQUIRED的區(qū)別是會新起一個事務,而不是使用父事務,所以是兩個截然不同的事務,ServiceB的執(zhí)行報錯,如果被ServiceA捕獲了,不會影響到ServiceA的回滾;
5>PROPAGATION_NOT_SUPPORTED
當前不支持事務,比方ServiceA.methodA的事務級別是PROPAGATION_REQUIRED 。
而ServiceB.methodB的事務級別是PROPAGATION_NOT_SUPPORTED ,那么當執(zhí)行到ServiceB.methodB時。
ServiceA.methodA的事務掛起。而他以非事務的狀態(tài)執(zhí)行完,再繼續(xù)ServiceA.methodA的事務。
6>PROPAGATION_NEVER
不能在事務中執(zhí)行。
如果ServiceA.methodA的事務級別是PROPAGATION_REQUIRED。
而ServiceB.methodB的事務級別是PROPAGATION_NEVER ,那么ServiceB.methodB就要拋出異常了。
7>PROPAGATION_NESTED
理解Nested的關鍵是savepoint。
他與PROPAGATION_REQUIRES_NEW的差別是,PROPAGATION_REQUIRES_NEW另起一個事務。將會與他的父事務相互獨立。
而Nested的事務和他的父事務是相依的,他的提交是要等和他的父事務一塊提交的。
也就是說,假設父事務最后回滾。他也要回滾的。
總結
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
mybatis?mapper.xml中如何根據數據庫類型選擇對應SQL語句
這篇文章主要介紹了mybatis?mapper.xml中如何根據數據庫類型選擇對應SQL語句,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-01-01JSON各種轉換問題(json轉List,json轉對象等)
這篇文章主要介紹了JSON各種轉換問題(json轉List,json轉對象等),本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-03-03Spring Cloud Eureka 服務上下線監(jiān)控的實現
這篇文章主要介紹了Spring Cloud Eureka 服務上下線監(jiān)控的實現,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-09-09