spring 事務(wù)增強(qiáng)源碼

spring 事務(wù)增強(qiáng) 接著上一篇 spring事務(wù)
上一篇文章,知道spring是通過什么把事務(wù)增強(qiáng)組合到切面里的语淘。
這一篇具體看看增強(qiáng)里都做了什么

核心抽象類TransactionAspectSupport的 invokeWithinTransaction方法

關(guān)鍵步驟

1诲宇、獲取事務(wù)管理對(duì)象 determineTransactionManager(txAttr)
 - @Transation上指定manager
 - TransactionAttribute 上指定的Qualifier
 - 默認(rèn)事務(wù)管理對(duì)象

從上面可以猜測(cè),多個(gè)事務(wù)管理委托給多個(gè)數(shù)據(jù)源

2惶翻、事物管理對(duì)象是否 有回調(diào)

2.1 回調(diào)型事物管理對(duì)象 CallbackPreferringPlatformTransactionManager
事物管理對(duì)象可以是非數(shù)據(jù)庫事物管理姑蓝,如kafka事物. 在執(zhí)行事物的過程中跟數(shù)據(jù)庫很不一樣,所有需要基礎(chǔ)該類自己實(shí)現(xiàn).

2.2 非回調(diào)型事物管理對(duì)象
通常就是數(shù)據(jù)庫事物管理, 開啟事物吕粗,執(zhí)行sql纺荧,關(guān)閉事物等操作

2.2.1、createTransactionIfNecessary
開啟事務(wù)颅筋,如果有必要的話宙暇;

  • 一種是無事務(wù)配置的,這種也是可以聲明切面配置事務(wù)增強(qiáng)议泵,不過是不會(huì)真正開啟事務(wù)占贫;

  • 另一種是有事務(wù)配置。
    getTransaction()獲取事務(wù)先口, 委托給doGetTransaction()方法獲取事務(wù)型奥;
    如 數(shù)據(jù)庫事務(wù)DataSourceTransactionManager的 doGetTransaction方法從DataSource獲取事務(wù)

    • 如果從DataSource獲取到的事務(wù)是開啟狀態(tài)的,則處理當(dāng)前事務(wù)描述的傳播特性池充,根據(jù)聲明的傳播特性做處理( 如桩引,聲明為不要事務(wù)缎讼,如果當(dāng)前獲取到了事務(wù)收夸,則拋出異常),處理完血崭,直接返回;
      具體處理 AbstractPlatformTransactionManager.handleExistingTransaction方法,根據(jù)傳播特性
      PROPAGATION_NEVER: 即不要事務(wù)卧惜,但卻得到了事務(wù),拋出異常.
      PROPAGATION_NOT_SUPPORTED: 即不支持事務(wù)夹纫,當(dāng)前事務(wù)會(huì)被掛起.
      PROPAGATION_REQUIRES_NEW:即需要新的事務(wù), 則當(dāng)前事務(wù)被掛起, 并且開啟新的事務(wù)
      PROPAGATION_NESTED: 即嵌套事務(wù), 如果事務(wù)管理器不允許嵌套事務(wù)則拋出異常. 如果連接支持jdbc savepoints則把當(dāng)前事務(wù)點(diǎn)當(dāng)作新事務(wù)返回(spring文檔的解析如下, 使用具有多個(gè)保存點(diǎn)的單個(gè)物理事務(wù)咽瓷,可以將其回滾到該保存點(diǎn)。這種部分回滾使內(nèi)部事務(wù)范圍觸發(fā)其范圍的回滾舰讹,盡管某些操作已回滾茅姜,但外部事務(wù)仍能夠繼續(xù)物理事務(wù)。此設(shè)置通常映射到JDBC保存點(diǎn)月匣,因此僅適用于JDBC資源事務(wù))钻洒。如果是JTA則已當(dāng)前事務(wù)開啟新事務(wù);

    • 如果從DataSource沒獲取到事務(wù)奋姿,或者事務(wù)是未開啟狀態(tài); 則嘗試掛起當(dāng)前事務(wù)(如果有)或者掛起所有事務(wù)(如果隔離級(jí)別是Synchronization的話,其他隔離級(jí)別則不掛起)
      之后開啟新的事務(wù)
      2.2.2 開啟新事務(wù)
      開啟新事物是DataSourceTransactionManager的doBegin方法素标,包括獲取連接, 設(shè)置手動(dòng)提交称诗,設(shè)置事務(wù)開啟狀態(tài)等, 因?yàn)殚_啟的事務(wù)跟數(shù)據(jù)庫連接有綁定關(guān)系,我們可以大膽的猜測(cè)头遭,事務(wù)完全就是數(shù)據(jù)庫連接的隔離寓免。

拿到事務(wù)后, 把事務(wù)綁定到當(dāng)前線程,并記錄綁定前的事務(wù)计维;
try {
① 之后就是執(zhí)行被代理對(duì)象的數(shù)據(jù)庫操作
catch() {
②如果有返回異常袜香,則判斷異常處理,是否需要回滾等
}
finally {
③ 清除事務(wù)鲫惶,并把上一個(gè)事務(wù)設(shè)置為當(dāng)前線程綁定的事務(wù)(如果有的話);
}
② 源碼里如果當(dāng)前事務(wù)出現(xiàn)異常的處理流程大概如下

completeTransactionAfterThrowing(txInfo, throwable) {
  if (txInfo != null && txInfo.getTransactionStatus() != null) {
    if (txInfo.transactionAttribute != null && txInfo.transactionAttribute.rollbackOn(ex)) {
      try {
          回滾
      }  catch() {
        有異常繼續(xù)往外拋出
      }
    }else {
      try {
          提交
      }catch() {
        有異常繼續(xù)往外發(fā)出
      }
    }  
  }

}

最后提交事務(wù), 這個(gè)過程也有可能回滾;

另一個(gè)非數(shù)據(jù)庫的事務(wù)本章不進(jìn)行分析, 請(qǐng)自行查閱源碼困鸥;

總結(jié)

spring事務(wù)不僅僅能管理數(shù)據(jù)庫事務(wù),也可以管理其他類型的事務(wù)剑按。
數(shù)據(jù)庫的事務(wù)管理依賴真實(shí)的數(shù)據(jù)庫的事務(wù)特性疾就。
通過spring聲明式事務(wù),使開發(fā)人員在開發(fā)數(shù)據(jù)庫操作時(shí)更加簡(jiǎn)單.
嵌套的事務(wù)傳播特性PROPAGATION_NESTED艺蝴, 能夠更細(xì)粒度的把控同事處理多個(gè)事務(wù)猬腰。
當(dāng)嵌套事務(wù)的內(nèi)部事務(wù)發(fā)聲異常,如果是事務(wù)可以處理的異常猜敢,則內(nèi)部事務(wù)回滾姑荷。 如果內(nèi)部事務(wù)無法處理的異常,則提交內(nèi)部事務(wù)缩擂,如果提交內(nèi)部事務(wù)的時(shí)候還拋出異常鼠冕,則異常往外一層事務(wù)拋出異常。

看一個(gè)題外例子胯盯。爆米豆的多數(shù)據(jù)源管理.
1懈费、首先知道baomidou的多數(shù)據(jù)源配置配置好連接屬性后,需要在業(yè)務(wù)類(通常是service類)上加@DS("xxx"), 這里的xx是數(shù)據(jù)源名稱. 如果不配置就用默認(rèn)數(shù)據(jù)源.
2博脑、通過之前spring的學(xué)習(xí)憎乙,爆米豆肯定會(huì)處理@DS這個(gè)注解。不出所料叉趣,DynamicDataSourceAnnotationAdvisor這個(gè)組合增強(qiáng)類就是處理@DS
3泞边、處理的過程就是把@DS聲明的數(shù)據(jù)源標(biāo)識(shí)放入鏈表里


image.png

4、當(dāng)數(shù)據(jù)庫操作的時(shí)候疗杉,會(huì)先獲取數(shù)據(jù)庫連接阵谚,而獲取連接時(shí)是通過數(shù)據(jù)源獲取,即最終通過數(shù)據(jù)源標(biāo)識(shí)獲取到真實(shí)數(shù)據(jù)源

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市梢什,隨后出現(xiàn)的幾起案子闻牡,更是在濱河造成了極大的恐慌,老刑警劉巖绳矩,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件罩润,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡翼馆,警方通過查閱死者的電腦和手機(jī)割以,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來应媚,“玉大人严沥,你說我怎么就攤上這事≈薪” “怎么了消玄?”我有些...
    開封第一講書人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長丢胚。 經(jīng)常有香客問我翩瓜,道長,這世上最難降的妖魔是什么携龟? 我笑而不...
    開封第一講書人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任兔跌,我火速辦了婚禮,結(jié)果婚禮上峡蟋,老公的妹妹穿的比我還像新娘坟桅。我一直安慰自己,他們只是感情好蕊蝗,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開白布仅乓。 她就那樣靜靜地躺著,像睡著了一般蓬戚。 火紅的嫁衣襯著肌膚如雪夸楣。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,688評(píng)論 1 305
  • 那天碌更,我揣著相機(jī)與錄音裕偿,去河邊找鬼洞慎。 笑死痛单,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的劲腿。 我是一名探鬼主播旭绒,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了挥吵?” 一聲冷哼從身側(cè)響起重父,我...
    開封第一講書人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎忽匈,沒想到半個(gè)月后房午,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡丹允,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年郭厌,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片雕蔽。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡折柠,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出批狐,到底是詐尸還是另有隱情扇售,我是刑警寧澤,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布嚣艇,位于F島的核電站承冰,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏食零。R本人自食惡果不足惜巷懈,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望慌洪。 院中可真熱鬧顶燕,春花似錦、人聲如沸冈爹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽频伤。三九已至恳谎,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間憋肖,已是汗流浹背因痛。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來泰國打工由境, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留猪腕,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓法焰,卻偏偏與公主長得像怎炊,于是被迫代替她去往敵國和親谭企。 傳聞我的和親對(duì)象是個(gè)殘疾皇子廓译,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

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