Spring事務(wù)回滾中的那些坑

? ? ? 在使用Spring注解進行事務(wù)控制的時候惫企,我們都習(xí)慣性用@Transactional 注解進行處理曙咽,但是指值得注意的一點是真正出現(xiàn)異常的時候,你的事務(wù)真正回滾了嗎怖辆?以下就列舉幾種添加@Transactional但是事務(wù)回滾沒有生效的情景邪码。

一裕菠、除非特殊配置只有定義在 public 方法上的 @Transactional 才能生效

? ? ? ? 原因是,Spring 默認通過動態(tài)代理的方式實現(xiàn) AOP闭专,對目標方法進行增強奴潘,private 方法無法代理到,Spring 自然也無法動態(tài)增強事務(wù)處理邏輯喻圃。

二、必須通過代理過的類從外部調(diào)用目標方法才能生效

Spring 通過 AOP 技術(shù)對方法進行增強粪滤,要調(diào)用增強過的方法必然是調(diào)用代理后的對象斧拍。

(1)同一個類中通過this調(diào)用的場景

圖1

? ? ? 圖1中的代碼邏輯通過this調(diào)用,拋出RuntimeException 是不會回滾事務(wù)的杖小,具體原因是this 指針代表對象自己肆汹,而不是Spring注入的代理愚墓。而只有通過代理訪問的方法才有可能進行回滾。而代理和this 的區(qū)別如圖2所示:this指的是TestController這個類昂勉,而真正經(jīng)歷Spring注入的代理是有“CGLIB”字樣的testService浪册。只有經(jīng)過testService代理直接調(diào)用的方法在出現(xiàn)異常的時候才會進行回滾。


圖2this和代理的區(qū)別

三岗照、不是所有的異常都會觸發(fā)回滾

? ? ? 默認情況下村象,出現(xiàn) RuntimeException(未檢查異常)或 Error 的時候,Spring 才會回滾事務(wù)攒至。此處需要解釋一下Java中的異常:

? ? ? Java中異常分為兩大類:checkedexception(檢查異常)和unchecked exception(未檢查異常)厚者。

? ? ? 未檢查異常也可以叫做RuntimeException(運行時異常),他們的主要區(qū)別:對于運行時異常迫吐,java編譯器不要求捕獲或者一定要繼續(xù)拋出,但是必須捕獲或者拋出檢查異常库菲。

? ? 常見的檢查異常:Exception,FileNotFoundException,IOException,SQLException。

? ? ? 常見的未檢查異常:? ? ? NullPointerException,ClassCastException,ArrayIndexsOutOfBoundsException,ArithmeticException(算術(shù)異常志膀,除0溢出)熙宇。

? ? (1)如果在代碼中對異常進行了try catch 操作使得RuntimeException(未檢查異常)或 Error 沒有拋出來,此時事務(wù)業(yè)務(wù)不會回滾溉浙,也可以正常執(zhí)行烫止。如果你希望自己捕獲異常進行處理的話,也沒關(guān)系放航,可以手動設(shè)置讓當前事務(wù)處于回滾狀態(tài)烈拒。具體代碼如圖3所示。


圖3

? (2)在注解中聲明广鳍,期望遇到所有的 Exception 都回滾事務(wù)(來突破默認不回滾受檢異常的限制)可以使用如下代碼對所有的異常進行回滾荆几。

@Transactional(rollbackFor = Exception.class)

四、多次數(shù)據(jù)庫操作回滾互不影響

在一個事務(wù)中有多個更新數(shù)據(jù)庫的操作赊时,但是又不想因為某一個數(shù)據(jù)庫操作的回滾影響到其他操作的完成吨铸。

為了描述方便我們把不需要回滾的稱為主流程,能夠回滾的是子流程祖秒。如果不做額外處理的話子流程如果回滾诞吱,即使子流程的代碼被try catch 住由于子流程已經(jīng)將該事務(wù)標注為回滾事務(wù),最后主流程也會跟著回滾竭缝。

解決這個問題的辦法讓子流程在獨立事務(wù)中運行房维,也就是為子流程注解加上 propagation = Propagation.REQUIRES_NEW 來設(shè)置 REQUIRES_NEW 方式的事務(wù)傳播策略,也就是執(zhí)行到這個方法時需要開啟新的事務(wù)抬纸,并掛起當前事務(wù)即可咙俩。

@Transactional(propagation = Propagation.REQUIRES_NEW)

總結(jié):

(1)我們務(wù)必確認調(diào)用 @Transactional 注解標記的方法是 public 的,并且是通過 Spring 注入的 Bean 進行調(diào)用的。

(2)因為異常處理不正確阿趁,導(dǎo)致事務(wù)雖然生效但出現(xiàn)異常時沒回滾膜蛔。Spring 默認只會對標記 @Transactional 注解的方法出現(xiàn)了 RuntimeException 和 Error 的時候回滾,如果我們的方法捕獲了異常脖阵,那么需要通過手動編碼處理事務(wù)回滾皂股。如果希望 Spring 針對其他異常也可以回滾,那么可以相應(yīng)配置 @Transactional 注解的 rollbackFor 和 noRollbackFor 屬性來覆蓋其默認設(shè)置命黔。

(3)如果方法涉及多次數(shù)據(jù)庫操作呜呐,并希望將它們作為獨立的事務(wù)進行提交或回滾,那么我們需要考慮進一步細化配置事務(wù)傳播方式纷铣,也就是 @Transactional 注解的 Propagation 屬性卵史。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市搜立,隨后出現(xiàn)的幾起案子以躯,更是在濱河造成了極大的恐慌,老刑警劉巖啄踊,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件忧设,死亡現(xiàn)場離奇詭異,居然都是意外死亡颠通,警方通過查閱死者的電腦和手機址晕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來顿锰,“玉大人谨垃,你說我怎么就攤上這事∨鹂兀” “怎么了刘陶?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長牢撼。 經(jīng)常有香客問我匙隔,道長,這世上最難降的妖魔是什么熏版? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任纷责,我火速辦了婚禮,結(jié)果婚禮上撼短,老公的妹妹穿的比我還像新娘再膳。我一直安慰自己,他們只是感情好曲横,可當我...
    茶點故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布喂柒。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪胳喷。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天夭织,我揣著相機與錄音吭露,去河邊找鬼。 笑死尊惰,一個胖子當著我的面吹牛讲竿,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播弄屡,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼题禀,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了膀捷?” 一聲冷哼從身側(cè)響起迈嘹,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎全庸,沒想到半個月后秀仲,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡壶笼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年神僵,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片覆劈。...
    茶點故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡保礼,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出责语,到底是詐尸還是另有隱情炮障,我是刑警寧澤,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布鹦筹,位于F島的核電站铝阐,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏铐拐。R本人自食惡果不足惜徘键,卻給世界環(huán)境...
    茶點故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望遍蟋。 院中可真熱鬧吹害,春花似錦、人聲如沸虚青。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽喳张。三九已至希停,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間攻走,已是汗流浹背谓媒。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工淆院, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人句惯。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓土辩,卻偏偏與公主長得像,于是被迫代替她去往敵國和親抢野。 傳聞我的和親對象是個殘疾皇子拷淘,可洞房花燭夜當晚...
    茶點故事閱讀 44,933評論 2 355