Spring中的事務(wù)隔離級(jí)別和傳播行為
Spring的事務(wù)隔離級(jí)別和事務(wù)的傳播行為是面試中經(jīng)??疾斓膯栴},做個(gè)簡單的總結(jié)。
傳播行為
在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; }
可以看出,默認(rèn)的值是Propagation.REQUIRED;
其他的還有:
- 1>
PROPAGATION_REQUIRED
支持當(dāng)前事務(wù),假設(shè)當(dāng)前沒有事務(wù)。就新建一個(gè)事務(wù)。 - 2>
PROPAGATION_SUPPORTS
支持當(dāng)前事務(wù),假設(shè)當(dāng)前沒有事務(wù),就以非事務(wù)方式運(yùn)行。 - 3>
PROPAGATION_MANDATORY
支持當(dāng)前事務(wù),假設(shè)當(dāng)前沒有事務(wù),就拋出異常。 - 4>
PROPAGATION_REQUIRES_NEW
新建事務(wù),假設(shè)當(dāng)前存在事務(wù)。把當(dāng)前事務(wù)掛起。 - 5>
PROPAGATION_NOT_SUPPORTED
以非事務(wù)方式運(yùn)行操作。假設(shè)當(dāng)前存在事務(wù),就把當(dāng)前事務(wù)掛起。 - 6>
PROPAGATION_NEVER
以非事務(wù)方式運(yùn)行,假設(shè)當(dāng)前存在事務(wù),則拋出異常。 - 7>
PROPAGATION_NESTED
如果當(dāng)前存在事務(wù),則在嵌套事務(wù)內(nèi)執(zhí)行。如果當(dāng)前沒有事務(wù),則進(jìn)行與PROPAGATION_REQUIRED類似的操作。
舉個(gè)例子進(jìn)行說明
ServiceA { void methodA() { ServiceB.methodB(); } } ServiceB { void methodB() { } }
1>PROPAGATION_REQUIRED
如果當(dāng)前執(zhí)行的事務(wù)不在另外一個(gè)事務(wù)里,就新起一個(gè)事務(wù);ServiceB和 ServiceA在同一個(gè)事務(wù)里面,ServiceB如果異常,則整個(gè)事務(wù)認(rèn)為是執(zhí)行失敗的,即便是在A里面try catch了異常也會(huì)導(dǎo)致A和B都回滾;同樣,即便B執(zhí)行成功,A執(zhí)行報(bào)錯(cuò)產(chǎn)生異常,那么A和B都會(huì)回滾的;
2>PROPAGATION_SUPPORTS
假設(shè)當(dāng)前在事務(wù)中。即以事務(wù)的形式執(zhí)行。假設(shè)當(dāng)前不再一個(gè)事務(wù)中,那么就以非事務(wù)的形式執(zhí)行;
3>PROPAGATION_MANDATORY
支持當(dāng)前事務(wù),假設(shè)當(dāng)前沒有事務(wù),就拋出異常,也就是說他必須在一個(gè)父事務(wù)中去執(zhí)行;否則就會(huì)拋出異常;
4>PROPAGATION_REQUIRES_NEW
新建事務(wù),假設(shè)當(dāng)前存在事務(wù),把當(dāng)前事務(wù)掛起;比如服務(wù)A的事務(wù)級(jí)別是PROPAGATION_REQUIRED,那么服務(wù)B的級(jí)別是PROPAGATION_REQUIRES_NEW;那么當(dāng)運(yùn)行到ServiceB.methodB的時(shí)候,ServiceA.methodA所在的事務(wù)就會(huì)掛起。
ServiceB.methodB會(huì)起一個(gè)新的事務(wù),等待ServiceB.methodB的事務(wù)完畢以后,他才繼續(xù)運(yùn)行;跟PROPAGATION_REQUIRED的區(qū)別是會(huì)新起一個(gè)事務(wù),而不是使用父事務(wù),所以是兩個(gè)截然不同的事務(wù),ServiceB的執(zhí)行報(bào)錯(cuò),如果被ServiceA捕獲了,不會(huì)影響到ServiceA的回滾;
5>PROPAGATION_NOT_SUPPORTED
當(dāng)前不支持事務(wù),比方ServiceA.methodA的事務(wù)級(jí)別是PROPAGATION_REQUIRED 。
而ServiceB.methodB的事務(wù)級(jí)別是PROPAGATION_NOT_SUPPORTED ,那么當(dāng)執(zhí)行到ServiceB.methodB時(shí)。
ServiceA.methodA的事務(wù)掛起。而他以非事務(wù)的狀態(tài)執(zhí)行完,再繼續(xù)ServiceA.methodA的事務(wù)。
6>PROPAGATION_NEVER
不能在事務(wù)中執(zhí)行。
如果ServiceA.methodA的事務(wù)級(jí)別是PROPAGATION_REQUIRED。
而ServiceB.methodB的事務(wù)級(jí)別是PROPAGATION_NEVER ,那么ServiceB.methodB就要拋出異常了。
7>PROPAGATION_NESTED
理解Nested的關(guān)鍵是savepoint。
他與PROPAGATION_REQUIRES_NEW的差別是,PROPAGATION_REQUIRES_NEW另起一個(gè)事務(wù)。將會(huì)與他的父事務(wù)相互獨(dú)立。
而Nested的事務(wù)和他的父事務(wù)是相依的,他的提交是要等和他的父事務(wù)一塊提交的。
也就是說,假設(shè)父事務(wù)最后回滾。他也要回滾的。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
mybatis?mapper.xml中如何根據(jù)數(shù)據(jù)庫類型選擇對(duì)應(yīng)SQL語句
這篇文章主要介紹了mybatis?mapper.xml中如何根據(jù)數(shù)據(jù)庫類型選擇對(duì)應(yīng)SQL語句,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01Java中復(fù)雜的Synchronized關(guān)鍵字使用方法詳解
Synchronized關(guān)鍵字是一個(gè)種鎖,其有很多名字,例如重量級(jí)鎖、悲觀鎖、可重入鎖、、非公平、對(duì)象鎖等等,這篇文章主要給大家介紹了關(guān)于Java中復(fù)雜的Synchronized關(guān)鍵字使用方法的相關(guān)資料,需要的朋友可以參考下2024-01-01JSON各種轉(zhuǎn)換問題(json轉(zhuǎn)List,json轉(zhuǎn)對(duì)象等)
這篇文章主要介紹了JSON各種轉(zhuǎn)換問題(json轉(zhuǎn)List,json轉(zhuǎn)對(duì)象等),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-03-03Java語言通過三種方法實(shí)現(xiàn)隊(duì)列的示例代碼
這篇文章主要介紹了Java語言通過三種方法來實(shí)現(xiàn)隊(duì)列的實(shí)例代碼,數(shù)組模擬隊(duì)列,通過對(duì)定義的了解,發(fā)現(xiàn)隊(duì)列很像我們的數(shù)組,下面我們通過實(shí)踐給大家詳細(xì)介紹,需要的朋友可以參考下2022-02-02Spring Cloud Eureka 服務(wù)上下線監(jiān)控的實(shí)現(xiàn)
這篇文章主要介紹了Spring Cloud Eureka 服務(wù)上下線監(jiān)控的實(shí)現(xiàn),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-09-09