Spring-tx

spring-tx,spring-jdbc模塊筆記,只涉及事務(wù)部分

核心類

@EnableTransactionManagement:引入TransactionManagementConfigurationSelector,根據(jù)參數(shù)判斷proxy/aspectj載入不同的解析對(duì)象,proxy模式下載入AutoProxyRegistrar和ProxyTransactionManagementConfiguration.

AutoProxyRegistrar:將InfrastructureAdvisorAutoProxyCreator加入到容器中.它將框架基礎(chǔ)設(shè)施Advisor(role=BeanDefinition.ROLE_INFRASTRUCTURE)生成對(duì)應(yīng)的aop代理

ProxyTransactionManagementConfiguration:載入了基于注解的aop基礎(chǔ)設(shè)施Bean.主要是將解析注解的Advisor對(duì)象加入到容器中

TransactionAttributeSource:事務(wù)源信息的獲取策略接口,載入的是AnnotationTransactionAttributeSource類,用于處理@Transaction注解
TransactionInterceptor-TransactionAspectSupport-invokeWithinTransaction執(zhí)行流程

BeanFactoryTransactionAttributeSourceAdvisor:通過StaticMethodMatcherPointcut將方法級(jí)過濾轉(zhuǎn)移到TransactionAttributeSource進(jìn)行判斷,advice部分轉(zhuǎn)到TransactionInterceptor進(jìn)行實(shí)現(xiàn).自身作為advisor加入到容器

事務(wù)管理器-事務(wù)的流程抽象

PlatformTransactionManager:事務(wù)管理器接口定義,使用較多的是DataSourceTransactionManager.它是以DataSource中的connection抽象的事務(wù)對(duì)象

TransactionStatus:存儲(chǔ)事務(wù)對(duì)象,掛起的上一個(gè)事務(wù)對(duì)象以及額外事務(wù)屬性的接口.它是主要的中間數(shù)據(jù),用于存儲(chǔ)原始連接信息以便后續(xù)的恢復(fù)連接信息

TransactionDefinition:事務(wù)屬性接口.傳播屬性,隔離級(jí)別,只讀等.它的實(shí)現(xiàn)主要是DefaultTransactionDefinition

TransactionTemplate:繼承DefaultTransactionDefinition,自身即含有事務(wù)狀態(tài),同時(shí)引入了PlatformTransactionManager進(jìn)行事務(wù)操作,還實(shí)現(xiàn)了
TransactionOperations接口,提供了手工事務(wù)操作入口.

核心流程

首先通過TransactionManager的getTransaction(td)方法獲得TransactionStatus對(duì)象,后面執(zhí)行對(duì)應(yīng)的回調(diào)方法,如果出異常那么回滾,如果正常執(zhí)行完成,那么提交操作,這兩個(gè)操作都需要之前返回的TransactionStatus對(duì)象作為入?yún)?

以DataSourceTransactionManager為例,描述完整的事務(wù)管理過程
getTransaction()方法,先通過doGetTransaction抽象方法獲取事務(wù)對(duì)象,事務(wù)對(duì)象是子類自己定義的,這里用的是DataSourceTransactionObject類,在doGetTransaction方法只是新建了DataSourceTransactionObject對(duì)象,嘗試通過ThreadLocal獲取之前的ConnectionHolder設(shè)置到當(dāng)前事務(wù)對(duì)象中.
然后判斷當(dāng)前線程是否存在被激活的事務(wù)(這里根據(jù)是否存在當(dāng)前事務(wù)對(duì)傳播屬性進(jìn)行了實(shí)現(xiàn))

如果有事務(wù)
那么檢查事務(wù)傳播行為,做出對(duì)應(yīng)的操作,直接返回結(jié)果
事務(wù)傳播行為對(duì)應(yīng)的操作(獲取連接=實(shí)際根據(jù)屬性進(jìn)行連接配置)
PROPAGATION_NEVER-拋異常
PROPAGATION_NOT_SUPPORTED-掛起當(dāng)前事務(wù),生成一個(gè)空的DefaultTransactionStatus返回(在非事務(wù)中執(zhí)行)
PROPAGATION_REQUIRES_NEW-掛起當(dāng)前事務(wù),將原事務(wù)對(duì)象與被掛起的資源放入DefaultTransactionStatus對(duì)象,并獲取連接(新建事務(wù))
PROPAGATION_NESTED-不掛起當(dāng)前事務(wù),將原事務(wù)對(duì)象放入DefaultTransactionStatus對(duì)象,并獲取連接(支持嵌套才可以,如果是DataSourceTM那么實(shí)際上還是同一連接)
其他情況-不掛起當(dāng)前事務(wù),將原事務(wù)對(duì)象放入DefaultTransactionStatus對(duì)象,直接返回,不獲取連接(支持當(dāng)前事務(wù)運(yùn)行PROPAGATION_REQUIRED或PROPAGATION_SUPPORTS)

如果沒有事務(wù)
根據(jù)對(duì)應(yīng)的傳播屬性做出對(duì)應(yīng)的操作并返回
PROPAGATION_MANDATORY-拋異常
PROPAGATION_REQUIRED&PROPAGATION_REQUIRES_NEW&PROPAGATION_NESTED-那么執(zhí)行以下操作
新建TransactionStatus對(duì)象(DefaultTransactionStatus),執(zhí)行doBegin抽象方法,這里doBegin方法先判斷事務(wù)對(duì)象是否有連接,如果沒有連接,那么調(diào)用DataSource.getConnection獲取一個(gè)新連接并包裝成ConnectionHolder對(duì)象放入事務(wù)對(duì)象內(nèi).然后對(duì)連接屬性進(jìn)行設(shè)置,有隔離級(jí)別,手動(dòng)提交.還要讀取Definition信息設(shè)置ConnectionHolder對(duì)象的屬性.同時(shí)將之前的連接信息存儲(chǔ)到事務(wù)對(duì)象中,用于后續(xù)提交或者回滾后恢復(fù)連接屬性操作.后面繼續(xù)判斷如果是新連接,那么線程綁定事務(wù)對(duì)象,同時(shí)設(shè)置事務(wù)激活狀態(tài),綁定事務(wù)隔離級(jí)別,只讀屬性,名稱等.返回TransactionStatus對(duì)象,讓使用者在可以拿到事務(wù)的屬性信息.結(jié)束創(chuàng)建事務(wù)流程.
其他情況-生成一個(gè)空的DefaultTransactionStatus返回(在非事務(wù)中執(zhí)行,如PROPAGATION_SUPPORTS,PROPAGATION_NOT_SUPPORTED)

中間在事務(wù)中執(zhí)行對(duì)應(yīng)的sql.

詳細(xì)說下這里連接對(duì)象的獲取過程.對(duì)于mybatis-spring來說,使用的是SpringManagedTransaction對(duì)象進(jìn)行管理DataSource來獲取連接的,這里的getConnection會(huì)轉(zhuǎn)到DataSourceUtils的getConnection中,它優(yōu)先判斷從綁定線程中可以獲取對(duì)應(yīng)的ConnectionHolder,并且事務(wù)是被激活的狀態(tài),那么從ConnectionHolder拿出連接直接返回,如果不是的話就獲取真實(shí)連接,再判斷當(dāng)前事務(wù)是否激活,如果是被激活的,那么注冊(cè)ConnectionSynchronization(用于清理資源)和將ConnectionHolder綁定到當(dāng)前線程.最后返回連接對(duì)象

最后如果拋出異常
回滾操作.先觸發(fā)綁定線程中的BeforeCompletion回調(diào),然后調(diào)用connection的rollback,根據(jù)有無異常,觸發(fā)AfterCompletion的回調(diào)并傳入不同參數(shù).最后觸發(fā)AfterCompletion的回調(diào)

如果沒有拋出異常
提交.檢查是否有本地/全局回滾標(biāo)志,如果有的話調(diào)用回滾操作,如果沒有,觸發(fā)BeforeCommit回調(diào),然后BeforeCompletion回調(diào),然后調(diào)用connection的commit.如果有異常觸發(fā)回滾,如果沒有,觸發(fā)AfterCommit回調(diào),最后觸發(fā)AfterCompletion回調(diào),然后進(jìn)行清理過程,清理掉所有線程綁定的對(duì)象,恢復(fù)連接屬性(自動(dòng)提交,隔離級(jí)別,只讀屬性),恢復(fù)之前掛起的事務(wù).當(dāng)前事務(wù)結(jié)束

事務(wù)特點(diǎn)

1.原子性:一個(gè)事務(wù)中所有對(duì)數(shù)據(jù)庫的操作是一個(gè)不可分割的操作序列颤殴,要么全做要么全不做
2.一致性:數(shù)據(jù)不會(huì)因?yàn)槭聞?wù)的執(zhí)行而遭到破壞
3.隔離性:一個(gè)事物的執(zhí)行李皇,不受其他事務(wù)的干擾册着,即并發(fā)執(zhí)行的事物之間互不干擾
4.持久性:一個(gè)事物一旦提交磕谅,它對(duì)數(shù)據(jù)庫的改變就是永久的菩鲜。

七個(gè)事務(wù)傳播屬性—傳播屬性的實(shí)現(xiàn)是spring實(shí)現(xiàn)的,有些傳播屬性(比如PROPAGATION_NESTED)主要是JTA考慮的
 PROPAGATION_REQUIRED -- 支持當(dāng)前事務(wù),如果當(dāng)前沒有事務(wù)葵礼,就新建一個(gè)事務(wù)萨醒。這是最常見的選擇。
 PROPAGATION_SUPPORTS -- 支持當(dāng)前事務(wù)写妥,如果當(dāng)前沒有事務(wù)拳球,就以非事務(wù)方式執(zhí)行。
 PROPAGATION_MANDATORY -- 支持當(dāng)前事務(wù)珍特,如果當(dāng)前沒有事務(wù)祝峻,就拋出異常。
 PROPAGATION_REQUIRES_NEW -- 新建事務(wù)扎筒,如果當(dāng)前存在事務(wù)莱找,把當(dāng)前事務(wù)掛起。
 PROPAGATION_NOT_SUPPORTED -- 以非事務(wù)方式執(zhí)行操作嗜桌,如果當(dāng)前存在事務(wù)奥溺,就把當(dāng)前事務(wù)掛起。
 PROPAGATION_NEVER -- 以非事務(wù)方式執(zhí)行骨宠,如果當(dāng)前存在事務(wù)浮定,則拋出異常。
 PROPAGATION_NESTED--如果當(dāng)前存在事務(wù)层亿,則在嵌套事務(wù)內(nèi)執(zhí)行壶唤。如果當(dāng)前沒有事務(wù),則進(jìn)行與PROPAGATION_REQUIRED類似的操作棕所。

五種隔離級(jí)別—隔離級(jí)別的實(shí)現(xiàn)是依靠數(shù)據(jù)庫自身實(shí)現(xiàn)的
隔離級(jí)別是指若干個(gè)并發(fā)的事務(wù)之間的隔離程度闸盔。
ISOLATION_DEFAULT--這是一個(gè)PlatfromTransactionManager默認(rèn)的隔離級(jí)別,使用數(shù)據(jù)庫默認(rèn)的事務(wù)隔離級(jí)別.另外四個(gè)與JDBC的隔離級(jí)別相對(duì)應(yīng)琳省;
ISOLATION_READ_UNCOMMITTED--這是事務(wù)最低的隔離級(jí)別迎吵,它充許別外一個(gè)事務(wù)可以看到這個(gè)事務(wù)未提交的數(shù)據(jù)。這種隔離級(jí)別會(huì)產(chǎn)生臟讀针贬,不可重復(fù)讀和幻像讀击费。
ISOLATION_READ_COMMITTED--保證一個(gè)事務(wù)修改的數(shù)據(jù)提交后才能被另外一個(gè)事務(wù)讀取。另外一個(gè)事務(wù)不能讀取該事務(wù)未提交的數(shù)據(jù)桦他。這種事務(wù)隔離級(jí)別可以避免臟讀出現(xiàn)蔫巩,但是可能會(huì)出現(xiàn)不可重復(fù)讀和幻像讀。
ISOLATION_REPEATABLE_READ--這種事務(wù)隔離級(jí)別可以防止臟讀,不可重復(fù)讀圆仔。但是可能出現(xiàn)幻像讀垃瞧。它保證了一個(gè)事務(wù)中的所有讀取操作時(shí)一致的結(jié)果,不受事務(wù)中其他事務(wù)提交的影響.但是會(huì)產(chǎn)生幻讀,比如說范圍查詢時(shí),每次查詢結(jié)果是一致的,但是其他事務(wù)新插入了符合條件的行,導(dǎo)致執(zhí)行的范圍更新比查詢結(jié)果多,就像產(chǎn)生的幻覺.部分?jǐn)?shù)據(jù)庫在RR級(jí)別已經(jīng)可以解決幻讀的問題了
ISOLATION_SERIALIZABLE--這是花費(fèi)最高代價(jià)但是最可靠的事務(wù)隔離級(jí)別。事務(wù)被處理為順序執(zhí)行坪郭。除了防止臟讀个从,不可重復(fù)讀外,還避免了幻像讀歪沃。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末嗦锐,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子沪曙,更是在濱河造成了極大的恐慌奕污,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,198評(píng)論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件液走,死亡現(xiàn)場(chǎng)離奇詭異菊值,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)育灸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門腻窒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人磅崭,你說我怎么就攤上這事儿子。” “怎么了砸喻?”我有些...
    開封第一講書人閱讀 167,643評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵柔逼,是天一觀的道長。 經(jīng)常有香客問我割岛,道長愉适,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,495評(píng)論 1 296
  • 正文 為了忘掉前任癣漆,我火速辦了婚禮维咸,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘惠爽。我一直安慰自己癌蓖,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評(píng)論 6 397
  • 文/花漫 我一把揭開白布婚肆。 她就那樣靜靜地躺著租副,像睡著了一般。 火紅的嫁衣襯著肌膚如雪较性。 梳的紋絲不亂的頭發(fā)上用僧,一...
    開封第一講書人閱讀 52,156評(píng)論 1 308
  • 那天结胀,我揣著相機(jī)與錄音,去河邊找鬼责循。 笑死糟港,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的沼死。 我是一名探鬼主播,決...
    沈念sama閱讀 40,743評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼崔赌,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼意蛀!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起健芭,我...
    開封第一講書人閱讀 39,659評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤县钥,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后慈迈,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體若贮,經(jīng)...
    沈念sama閱讀 46,200評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評(píng)論 3 340
  • 正文 我和宋清朗相戀三年痒留,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了谴麦。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,424評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡伸头,死狀恐怖匾效,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情恤磷,我是刑警寧澤面哼,帶...
    沈念sama閱讀 36,107評(píng)論 5 349
  • 正文 年R本政府宣布,位于F島的核電站扫步,受9級(jí)特大地震影響魔策,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜河胎,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評(píng)論 3 333
  • 文/蒙蒙 一闯袒、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧游岳,春花似錦搁吓、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春芯咧,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背仁连。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評(píng)論 1 271
  • 我被黑心中介騙來泰國打工恼五, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留昌罩,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,798評(píng)論 3 376
  • 正文 我出身青樓灾馒,卻偏偏與公主長得像茎用,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子睬罗,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評(píng)論 2 359

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

  • spring transaction 筆記 事務(wù)的特性(ACID) 原子性(Atomicity)轨功、一致性(Cons...
    NoSuchElementEx閱讀 6,048評(píng)論 0 0
  • 一、PlatformTransactionManager 1容达、架構(gòu)設(shè)計(jì)理念讓事務(wù)的關(guān)注點(diǎn)與數(shù)據(jù)訪問關(guān)注點(diǎn)分離...
    七離_82cd閱讀 7,454評(píng)論 0 3
  • ORA-00001: 違反唯一約束條件 (.) 錯(cuò)誤說明:當(dāng)在唯一索引所對(duì)應(yīng)的列上鍵入重復(fù)值時(shí)古涧,會(huì)觸發(fā)此異常。 O...
    我想起個(gè)好名字閱讀 5,333評(píng)論 0 9
  • 事務(wù)的嵌套概念 所謂事務(wù)的嵌套就是兩個(gè)事務(wù)方法之間相互調(diào)用花盐。spring事務(wù)開啟 羡滑,或者是基于接口的或者是基于類的...
    jackcooper閱讀 1,423評(píng)論 0 10
  • 黯然銷魂者 唯別而已矣 生離死別 又豈止是黯然銷魂呢 親愛的 還記得我們一起去濕地公園 你簡(jiǎn)直有才到飛起 你就這樣...
    重復(fù)走閱讀 109評(píng)論 0 0