SpringBoot事務(wù)控制

轉(zhuǎn)自【一起來(lái)學(xué)SpringBoot(八)事務(wù)的控制 - fulinlin的博客 - CSDN博客】https://blog.csdn.net/qq_32867467/article/details/82944473

編程式事務(wù)

編程式事務(wù)管理使用TransactionTemplate或者直接使用底層的PlatformTransactionManager屁魏。對(duì)于編程式事務(wù)管理,spring推薦使用TransactionTemplate。

聲明式事務(wù)

編程式事務(wù)每次實(shí)現(xiàn)都要單獨(dú)實(shí)現(xiàn)慈格,但業(yè)務(wù)量大功能復(fù)雜時(shí)腾供,使用編程式事務(wù)無(wú)疑是痛苦的炕泳,而聲明式事務(wù)不同将宪,聲明式事務(wù)屬于無(wú)侵入式胧谈,不會(huì)影響業(yè)務(wù)邏輯的實(shí)現(xiàn)过椎。

聲明式事務(wù)管理使用了 AOP 實(shí)現(xiàn)的室梅,本質(zhì)就是在目標(biāo)方法執(zhí)行前后進(jìn)行攔截。在目標(biāo)方法執(zhí)行前加入或創(chuàng)建一個(gè)事務(wù),在執(zhí)行方法執(zhí)行后亡鼠,根據(jù)實(shí)際情況選擇提交或是回滾事務(wù)赏殃。

@Transactional可以作用于接口、接口方法拆宛、類以及類方法上嗓奢。當(dāng)作用于類上時(shí),該類的所有 public 方法將都具有該類型的事務(wù)屬性浑厚,同時(shí)股耽,我們也可以在方法級(jí)別使用該標(biāo)注來(lái)覆蓋類級(jí)別的定義。因此可以在Service層和Controller層使用钳幅。

在此處需要特別注意的是物蝙,此@Transactional注解來(lái)自org.springframework.transaction.annotation包,而不是javax.transaction敢艰。

這里特意說(shuō)明一下

1.如果在接口诬乞、實(shí)現(xiàn)類或方法上都指定了@Transactional注解,則優(yōu)先級(jí)順序?yàn)榉椒?gt;實(shí)現(xiàn)類>接口钠导;

2.建議只在實(shí)現(xiàn)類或?qū)崿F(xiàn)類的方法上使用@Transactional震嫉,而不要在接口上使用,這是因?yàn)槿绻褂肑DK代理機(jī)制(基于接口的代理)是沒(méi)問(wèn)題牡属;而使用使用CGLIB代理(繼承)機(jī)制時(shí)就會(huì)遇到問(wèn)題票堵,因?yàn)槠涫褂没陬惖拇矶皇墙涌冢@是因?yàn)榻涌谏系腀Transactional注解是“不能繼承的”逮栅;

3.Spring提供了一個(gè)@EnableTransactionManagement注解在配置類上來(lái)開(kāi)啟聲明式事務(wù)的支持悴势。使用了@EnableTransactionManagement后,Spring容器會(huì)自動(dòng)掃描注解@Transactional的方法和類措伐。

@Transactional參數(shù)功能名稱描述:

readOnly 該屬性用于設(shè)置當(dāng)前事務(wù)是否為只讀事務(wù)特纤,設(shè)置為true表示只讀,false則表示可讀寫(xiě)侥加,默認(rèn)值為false捧存。例如:@Transactional(readOnly=true)

rollbackFor 該屬性用于設(shè)置需要進(jìn)行回滾的異常類數(shù)組,當(dāng)方法中拋出指定異常數(shù)組中的異常時(shí)担败,則進(jìn)行事務(wù)回滾矗蕊。例如:指定單一異常類:@Transactional(rollbackFor=RuntimeException.class)指定多個(gè)異常類:@Transactional(rollbackFor={RuntimeException.class, Exception.class})

rollbackForClassName 該屬性用于設(shè)置需要進(jìn)行回滾的異常類名稱數(shù)組,當(dāng)方法中拋出指定異常名稱數(shù)組中的異常時(shí)氢架,則進(jìn)行事務(wù)回滾。例如:指定單一異常類名稱@Transactional(rollbackForClassName=”RuntimeException”)指定多個(gè)異常類名稱:@Transactional(rollbackForClassName={“RuntimeException”,”Exception”})

noRollbackFor 該屬性用于設(shè)置不需要進(jìn)行回滾的異常類數(shù)組朋魔,當(dāng)方法中拋出指定異常數(shù)組中的異常時(shí)岖研,不進(jìn)行事務(wù)回滾。例如:指定單一異常類:@Transactional(noRollbackFor=RuntimeException.class)指定多個(gè)異常類:@Transactional(noRollbackFor={RuntimeException.class, Exception.class})

noRollbackForClassName 該屬性用于設(shè)置不需要進(jìn)行回滾的異常類名稱數(shù)組,當(dāng)方法中拋出指定異常名稱數(shù)組中的異常時(shí)孙援,不進(jìn)行事務(wù)回滾害淤。例如:指定單一異常類名稱:@Transactional(noRollbackForClassName=”RuntimeException”)指定多個(gè)異常類名稱:@Transactional(noRollbackForClassName={“RuntimeException”,”Exception”})

propagation 該屬性用于設(shè)置事務(wù)的傳播行為。例如:@Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true)

isolation 該屬性用于設(shè)置底層數(shù)據(jù)庫(kù)的事務(wù)隔離級(jí)別拓售,事務(wù)隔離級(jí)別用于處理多事務(wù)并發(fā)的情況窥摄,通常使用數(shù)據(jù)庫(kù)的默認(rèn)隔離級(jí)別即可,基本不需要進(jìn)行設(shè)置

timeout 該屬性用于設(shè)置事務(wù)的超時(shí)秒數(shù)础淤,默認(rèn)值為-1表示永不超時(shí)

事務(wù)屬性

事務(wù)屬性包含以下五個(gè)方面:隔離級(jí)別崭放、傳播行為、回滾規(guī)則鸽凶、事務(wù)超時(shí)币砂、只讀。

注意點(diǎn)

僅對(duì) public 方法有效

只有 @Transactional 注解應(yīng)用到 public 方法上才能進(jìn)行事務(wù)管理玻侥。這是因?yàn)?Spring 在 AOP 事務(wù)注解時(shí)决摧,在讀取注解上的屬性方法中,會(huì)優(yōu)先判斷方法是否是 public凑兰,如果不是 public掌桩,就不會(huì)讀取事務(wù)配置信息。

AOP 的自調(diào)用問(wèn)題

在 Spring 的 AOP 代理下姑食,只有目標(biāo)方法由外部調(diào)用波岛,目標(biāo)方法才由 Spring 生成的代理對(duì)象來(lái)管理。也就是說(shuō)矢门,在同一個(gè)類中的一個(gè) @Transactional 方法中盆色,去調(diào)用另一個(gè) @Transactional 方法,會(huì)導(dǎo)致第二個(gè)方法的事務(wù)無(wú)效祟剔,被 Spring AOP 所忽略隔躲。

對(duì)方法try-catch

對(duì)方法進(jìn)行try-catch后 捕捉異常,則事物就失效了物延,如果既想try-catch又想事物回歸怎么辦呢宣旱?這樣就行了。

多個(gè)事務(wù)管理器的處理

關(guān)于事務(wù)管理器叛薯,不管是JPA還是JDBC等都實(shí)現(xiàn)自接口 PlatformTransactionManager浑吟。 如果你添加的是 spring-boot-starter-jdbc 依賴,框架會(huì)默認(rèn)注入 DataSourceTransactionManager 實(shí)例耗溜。如果你添加的是 spring-boot-starter-data-jpa 依賴组力,框架會(huì)默認(rèn)注入 JpaTransactionManager 實(shí)例。

這些SpringBoot為我們自動(dòng)做了抖拴,對(duì)我們并不透明燎字。如果你項(xiàng)目做的比較大腥椒,添加的持久化依賴比較多,我們還是會(huì)選擇人為的指定使用哪個(gè)事務(wù)管理器候衍。代碼如下:

@EnableTransactionManagement

@SpringBootApplication

public class ProfiledemoApplication {

// 其中 dataSource 框架會(huì)自動(dòng)為我們注入

@Bean

public PlatformTransactionManager txManager(DataSource dataSource) {

return new DataSourceTransactionManager(dataSource);

}

@Bean

public Object testBean(PlatformTransactionManager platformTransactionManager) {

System.out.println(">>>>>>>>>>" + platformTransactionManager.getClass().getName());

return new Object();

}

public static void main(String[] args) {

SpringApplication.run(ProfiledemoApplication.class, args);

}

}

在Spring容器中笼蛛,我們手工注解@Bean 將被優(yōu)先加載,框架不會(huì)重新實(shí)例化其他的 PlatformTransactionManager 實(shí)現(xiàn)類蛉鹿。

然后在Service中滨砍,被 @Transactional 注解的方法,將支持事務(wù)妖异。如果注解在類上惋戏,則整個(gè)類的所有方法都默認(rèn)支持事務(wù)。

對(duì)于同一個(gè)工程中存在多個(gè)事務(wù)管理器要怎么處理随闺,請(qǐng)看下面的實(shí)例日川,具體說(shuō)明請(qǐng)看代碼中的注釋。

@EnableTransactionManagement// 開(kāi)啟注解事務(wù)管理矩乐,等同于xml配置文件中的 <tx:annotation-driven />

@SpringBootApplication

public class ProfiledemoApplication implements TransactionManagementConfigurer {

@Resource(name="txManager2")

private PlatformTransactionManager txManager2;

// 創(chuàng)建事務(wù)管理器1

@Bean(name = "txManager1")

public PlatformTransactionManager txManager(DataSource dataSource) {

return new DataSourceTransactionManager(dataSource);

}

// 創(chuàng)建事務(wù)管理器2

@Bean(name = "txManager2")

public PlatformTransactionManager txManager2(EntityManagerFactory factory) {

return new JpaTransactionManager(factory);

}

// 實(shí)現(xiàn)接口TransactionManagementConfigurer 方法龄句,其返回值代表在擁有多個(gè)事務(wù)管理器的情況下默認(rèn)使用的事務(wù)管理器

@Override

public PlatformTransactionManager annotationDrivenTransactionManager() {

return txManager2;

}

public static void main(String[] args) {

SpringApplication.run(ProfiledemoApplication.class, args);

}

}

@Component

public class DevSendMessage implements SendMessage {

// 使用value具體指定使用哪個(gè)事務(wù)管理器

@Transactional(value="txManager1")

@Override

public void send() {

System.out.println(">>>>>>>>Dev Send()<<<<<<<<");

send2();

}

// 在存在多個(gè)事務(wù)管理器的情況下,如果沒(méi)有使用value具體指定散罕,則默認(rèn)使用方法? annotationDrivenTransactionManager() 返回的事務(wù)管理器

@Transactional

public void send2() {

System.out.println(">>>>>>>>Dev Send2()<<<<<<<<");

}

}

注:如果Spring容器中存在多個(gè) PlatformTransactionManager 實(shí)例分歇,并且沒(méi)有實(shí)現(xiàn)接口 TransactionManagementConfigurer 指定默認(rèn)值,在我們?cè)诜椒ㄉ鲜褂米⒔?@Transactional 的時(shí)候欧漱,就必須要用value指定职抡,如果不指定,則會(huì)拋出異常误甚。

對(duì)于系統(tǒng)需要提供默認(rèn)事務(wù)管理的情況下缚甩,實(shí)現(xiàn)接口TransactionManagementConfigurer 指定。

對(duì)有的系統(tǒng)窑邦,為了避免不必要的問(wèn)題擅威,在業(yè)務(wù)中必須要明確指定 @Transactional 的 value 值的情況下。不建議實(shí)現(xiàn)接口 TransactionManagementConfigurer冈钦,這樣控制臺(tái)會(huì)明確拋出異常郊丛,開(kāi)發(fā)人員就不會(huì)忘記主動(dòng)指定。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末瞧筛,一起剝皮案震驚了整個(gè)濱河市厉熟,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌较幌,老刑警劉巖揍瑟,帶你破解...
    沈念sama閱讀 211,265評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異乍炉,居然都是意外死亡月培,警方通過(guò)查閱死者的電腦和手機(jī)嘁字,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)杉畜,“玉大人,你說(shuō)我怎么就攤上這事衷恭〈说” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,852評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵随珠,是天一觀的道長(zhǎng)灭袁。 經(jīng)常有香客問(wèn)我,道長(zhǎng)窗看,這世上最難降的妖魔是什么茸歧? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,408評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮显沈,結(jié)果婚禮上软瞎,老公的妹妹穿的比我還像新娘。我一直安慰自己拉讯,他們只是感情好涤浇,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著魔慷,像睡著了一般只锭。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上院尔,一...
    開(kāi)封第一講書(shū)人閱讀 49,772評(píng)論 1 290
  • 那天蜻展,我揣著相機(jī)與錄音,去河邊找鬼邀摆。 笑死纵顾,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的隧熙。 我是一名探鬼主播片挂,決...
    沈念sama閱讀 38,921評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼贞盯!你這毒婦竟也來(lái)了音念?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,688評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤躏敢,失蹤者是張志新(化名)和其女友劉穎闷愤,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體件余,經(jīng)...
    沈念sama閱讀 44,130評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡讥脐,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評(píng)論 2 325
  • 正文 我和宋清朗相戀三年遭居,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片旬渠。...
    茶點(diǎn)故事閱讀 38,617評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡俱萍,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出告丢,到底是詐尸還是另有隱情枪蘑,我是刑警寧澤,帶...
    沈念sama閱讀 34,276評(píng)論 4 329
  • 正文 年R本政府宣布岖免,位于F島的核電站岳颇,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏颅湘。R本人自食惡果不足惜话侧,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望闯参。 院中可真熱鬧瞻鹏,春花似錦、人聲如沸赢赊。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,740評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)释移。三九已至叭披,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間玩讳,已是汗流浹背涩蜘。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,967評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留熏纯,地道東北人同诫。 一個(gè)月前我還...
    沈念sama閱讀 46,315評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像樟澜,于是被迫代替她去往敵國(guó)和親误窖。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • 一秩贰、事務(wù)簡(jiǎn)單介紹 事務(wù)指邏輯上的一組操作霹俺,組成這組操作的各個(gè)單元,要不全部成功毒费,要不全部不成功丙唧。 1.1 事...
    tuacy閱讀 116,559評(píng)論 11 110
  • 這部分的參考文檔涉及數(shù)據(jù)訪問(wèn)和數(shù)據(jù)訪問(wèn)層和業(yè)務(wù)或服務(wù)層之間的交互。 Spring的綜合事務(wù)管理支持覆蓋很多細(xì)節(jié)觅玻,然...
    竹天亮閱讀 1,033評(píng)論 0 0
  • 原文:http://www.cnblogs.com/younggun/archive/2013/07/16/319...
    Feng_Sir閱讀 792評(píng)論 0 3
  • 引言: 在Spring中@Transactional提供一種控制事務(wù)管理的快捷手段想际,但是很多人都只是@Transa...
    _許帥_閱讀 861評(píng)論 0 2
  • 11. 事務(wù)管理 11.1 Spring Framework事務(wù)管理介紹 廣泛的事務(wù)支持是Spring Frame...
    此魚(yú)不得水閱讀 621評(píng)論 0 0