10、分布式事務(wù)-Seata-AT模式-上

章節(jié)歸屬

分布式事務(wù)系列

1、背景

伴隨著高性能的分布式系統(tǒng)演進(jìn)琴昆,我們必然會(huì)經(jīng)歷 通過橫向擴(kuò)展節(jié)點(diǎn) 提高非熱點(diǎn)數(shù)據(jù)的并發(fā)性能;而橫向擴(kuò)展節(jié)點(diǎn)實(shí)際是如下2方面的擴(kuò)展變化:

  1. 擴(kuò)展功能節(jié)點(diǎn)(對(duì)應(yīng)應(yīng)用的微服務(wù)化改造)
  2. 擴(kuò)展數(shù)據(jù)節(jié)點(diǎn)(對(duì)應(yīng)增加數(shù)據(jù)分片)

這些變化自然就引發(fā) 原來調(diào)用一個(gè)服務(wù)的一個(gè)接口就完成的功能馆揉,現(xiàn)在需要協(xié)同調(diào)用多個(gè)服務(wù)的多個(gè)接口才能完成业舍。相信我們都遇到過因網(wǎng)絡(luò)、機(jī)器升酣、程序等不可靠舷暮,引發(fā)的數(shù)據(jù)一致性的問題。而數(shù)據(jù)的一致性與系統(tǒng)的可擴(kuò)展性和高可用同樣重要 是【基礎(chǔ)IT架構(gòu)】支撐業(yè)務(wù)高質(zhì)量轉(zhuǎn)型升級(jí)的重點(diǎn)也是難點(diǎn)噩茄。從螞蟻金服的分布事務(wù)產(chǎn)品十幾年的Roadmap可以看出其在數(shù)據(jù)一致性方面的堅(jiān)持和不易(如今能快速使用他們的積累下面,幸甚至哉!)绩聘,如下圖所示:

image.png

從官宣得知沥割,螞蟻金服從微服務(wù)演進(jìn)開始至今,大量的應(yīng)用采用了TCC事務(wù)模型凿菩,2017年推出了FMT模式机杜,類比即Seata中的AT模式。

2衅谷、起源

既然10年時(shí)間都是TCC模式椒拗,為什么會(huì)推出FMT(AT)模式呢,并且Seata官方也首推AT模式获黔,注意AT是 Auto Transaction 的縮寫蚀苛,這個(gè)話題我覺得可以借助汽車從手動(dòng)擋到自動(dòng)擋的演進(jìn)來討論,早期全是自動(dòng)擋汽車肢执,但2021年統(tǒng)計(jì)顯示自動(dòng)擋車占比超過80%枉阵,為什么會(huì)這樣呢:

  1. 自動(dòng)檔汽車比手動(dòng)檔汽車更容易操作
    自動(dòng)檔汽車可以自動(dòng)匹配檔位與速度,而手動(dòng)檔汽車則需要根據(jù)行駛速度预茄,手動(dòng)實(shí)現(xiàn)檔位的轉(zhuǎn)換兴溜。因此,自動(dòng)檔汽車更容易操作耻陕,更方便駕駛拙徽,尤其是對(duì)于缺少駕車經(jīng)驗(yàn)的司機(jī)而言,自動(dòng)檔汽車是非常好的選擇诗宣。
  2. 自動(dòng)檔汽車駕車舒適度更高
    自動(dòng)檔汽車不用進(jìn)行手動(dòng)換擋膘怕,不需要手和腳的密切配合。自動(dòng)檔汽車在駕駛時(shí)可以不用一直進(jìn)行換檔位召庞,只需掌控踩油門的深淺岛心,就可以輕松實(shí)現(xiàn)速度的轉(zhuǎn)換来破,因此,很大程度上可以提高駕車舒適度忘古。
  3. 自動(dòng)檔汽車安全系數(shù)更高
    對(duì)于新手來講徘禁,讓駕駛者專注于駕駛,避免額外的操控髓堪,做的少就錯(cuò)的少送朱,錯(cuò)的少自然就降低事故率。

若將誕生于早期的TCC分布式事務(wù)模式類比成手動(dòng)擋駕駛模式干旁,那么Seata-AT模式就是當(dāng)下主流的自動(dòng)擋駕駛模式驶沼,正如有了自動(dòng)變速箱后,駕駛者不需要知曉離合器争群、檔位的存在回怜,不用關(guān)注離合器、檔位和油門三者之間那微妙協(xié)作祭阀;開發(fā)著不需要再去關(guān)心提供TCC三個(gè)方法鹉戚,并掌控他們之間的協(xié)作;這些繁瑣且難度高的事項(xiàng)由框架層托管专控,開發(fā)者只關(guān)注如何編寫SQL來實(shí)現(xiàn)業(yè)務(wù)邏輯即可抹凳。

3、核心思想

Seata AT 模式 是基于數(shù)據(jù)源代理實(shí)現(xiàn)的伦腐,是增強(qiáng)型2pc模式赢底;其核心思想就是由框架托管分布式事務(wù):通過代理DataSource中的Connection,攔截SQL執(zhí)行柏蘑,改變其原執(zhí)行邏輯幸冻,由代理引入額外的機(jī)制,加入額外的邏輯完成分布式事務(wù)咳焚。

4洽损、角色和職責(zé)

4.1、基于JDBC驅(qū)動(dòng)操作DB革半,提供服務(wù)

跟正常寫業(yè)務(wù)服務(wù)沒有區(qū)別碑定。

4.2、角色

Seata-AT模式的實(shí)現(xiàn)中有3個(gè)重要角色

TC (Transaction Coordinator) - 事務(wù)協(xié)調(diào)者

維護(hù)全局和分支事務(wù)的狀態(tài)又官,驅(qū)動(dòng)全局事務(wù)提交或回滾延刘。

TM (Transaction Manager) - 事務(wù)管理器(發(fā)起方)

定義全局事務(wù)的范圍:開始全局事務(wù)、提交或回滾全局事務(wù)六敬。

RM (Resource Manager) - 資源管理器(參與者)

提供TCC服務(wù)碘赖,與TC交談以注冊(cè)分支事務(wù)和報(bào)告分支事務(wù)的狀態(tài),并驅(qū)動(dòng)分支事務(wù)提交或回滾。

4.3普泡、二階段的職責(zé)分工

AT 模式對(duì)業(yè)務(wù)無任何侵入播掷,其一階段和二階段的提交\回滾均由 Seata 框架自動(dòng)生成,用戶只需編寫“業(yè)務(wù) SQL”劫哼,便能輕松接入分布式事務(wù)叮趴。

image.png
4.3.1 第一階段:

如下圖所示,Seata 會(huì)攔截“業(yè)務(wù) SQL”权烧,首先解析 SQL 語義,找到“業(yè)務(wù) SQL”要更新的業(yè)務(wù)數(shù)據(jù)伤溉,在業(yè)務(wù)數(shù)據(jù)被更新前般码,將其保存成“before image”,然后執(zhí)行“業(yè)務(wù) SQL”更新業(yè)務(wù)數(shù)據(jù)乱顾,在業(yè)務(wù)數(shù)據(jù)更新之后板祝,再將其保存成“after image”,最后生成行鎖走净。以上操作全部在一個(gè)本地?cái)?shù)據(jù)庫(kù)事務(wù)內(nèi)完成券时,這樣保證了一階段操作的原子性。

image.png

第一階段總結(jié)來說即是:業(yè)務(wù)sql和記錄回滾日志的sql在同一個(gè)本地事務(wù)中提交伏伯,提交后即釋放本地連接資源橘洞。

4.3.2. 第二階段
4.3.2.1 二階段-提交

因?yàn)椤皹I(yè)務(wù) SQL”在一階段已經(jīng)提交至數(shù)據(jù)庫(kù), 所以 Seata 框架只需將一階段保存的快照數(shù)據(jù)和行鎖刪掉说搅,完成數(shù)據(jù)清理即可炸枣。


image.png
4.3.2.2 二階段-回滾

Seata 需要回滾一階段已經(jīng)執(zhí)行的“業(yè)務(wù) SQL”,還原業(yè)務(wù)數(shù)據(jù)弄唧∈食Γ回滾方式便是用“before image”還原業(yè)務(wù)數(shù)據(jù);但在還原前要首先要校驗(yàn)臟寫候引,對(duì)比“數(shù)據(jù)庫(kù)當(dāng)前業(yè)務(wù)數(shù)據(jù)”和 “after image”侯养,如果兩份數(shù)據(jù)完全一致就說明沒有臟寫,可以還原業(yè)務(wù)數(shù)據(jù)澄干,如果不一致就說明有臟寫逛揩,出現(xiàn)臟寫就需要轉(zhuǎn)人工處理。


image.png

第二階段總結(jié)來說即是:TC向RM發(fā)起提交或回滾傻寂;提交的話通過異步進(jìn)行回滾日志的自動(dòng)清理息尺,事務(wù)得以馬上結(jié)束;回滾的話疾掰,通過一階段的回滾日志搂誉,自動(dòng)生成并執(zhí)行補(bǔ)償回滾的數(shù)據(jù)操作。

5静檬、工作原理

5.1炭懊、整體架構(gòu)

Seata-AT模式整體架構(gòu)如下圖所示:

image.png
5.2并级、核心流程
5.2.1、第一階段
image.png

以一個(gè)原本有100塊的賬戶扣掉10塊錢為例:update account seg balance=balance-10 WHERE uId='001'

  1. 解析SQL:解析得到操作類型侮腹、表和條件嘲碧,這里SQL操作類型是update,表是account父阻,條件是uid='001' 信息
  2. 生成before image:從 account表中檢索uId='001'的賬戶在執(zhí)行update之前的余額愈涩,得到了100,即before image的結(jié)果集加矛,作為回滾時(shí)使用的數(shù)據(jù)
  3. 執(zhí)行業(yè)務(wù)SQL:update account set balance=balance-10 where uId='001'
  4. 生成after image:從 account表中檢索uId='001'的賬戶的在執(zhí)行update之后的余額履婉,得到了90,即after image的結(jié)果集斟览,作為回滾時(shí)用于比對(duì)判斷是否有臟寫的依據(jù)
  5. 記錄undolog:將前后鏡像組合毁腿,以 json格式壓縮一下存到 UNDO_LOG 表中
  6. 提交前,RM向TC注冊(cè)分支:這里會(huì)申請(qǐng) account 表中主鍵值等于 '001' 的記錄的全局鎖苛茂,鎖的粒度是:服務(wù)+表+記錄ID
  7. 提交本地事務(wù):將業(yè)務(wù)數(shù)據(jù)的更新和undolog的記錄 一并提交
  8. 將本地事務(wù)提交的結(jié)果上報(bào)給 TC
5.2.2已烤、第二階段-提交
image.png
  1. TM 向 TC 發(fā)起全局事務(wù)提交
  2. TC 向 各RM 發(fā)起分支提交(傳遞XID)
  3. RM 接收到請(qǐng)求后放入一個(gè)異步任務(wù)的隊(duì)列中,并立即返回TC提交成功
  4. 異步任務(wù)批量地刪除相應(yīng) undolog
5.2.3妓羊、第二階段-回滾
image.png
  1. 收到 TC 的分支回滾請(qǐng)求胯究,開啟一個(gè)本地事務(wù)
  2. 通過 XID 和 Branch ID 找到相應(yīng)的 undolog
  3. 校驗(yàn)臟寫:后鏡像與當(dāng)前數(shù)據(jù)庫(kù)數(shù)據(jù)比較,如有不同則說明已被當(dāng)前全局事務(wù)外的動(dòng)作做了修改侍瑟,此時(shí)需根據(jù)配置策略來處理
  4. 還原數(shù)據(jù):根據(jù)前后鏡像唐片,生成逆向SQL并“回滾”(相當(dāng)于重新寫入一次)
  5. 刪除undolog
  6. 提交本地事務(wù),并把本地事務(wù)的執(zhí)行結(jié)果(即分支事務(wù)回滾的結(jié)果)上報(bào)給 TC
5.3涨颜、注意事項(xiàng)
  1. 空回滾费韭、 防懸掛、 冪等控制
    在TCC模式下,需要考慮 空回滾、 防懸掛悄蕾、 冪等控制的情況习绢。但是在AT模式下芋肠,不需要有業(yè)務(wù)層去關(guān)注這些問題,因?yàn)榭蚣芸梢酝ㄟ^AT模式中生成的前后鏡像,自動(dòng)處理以上問題。
  2. 數(shù)據(jù)隔離
    本地事務(wù)的支持是seata實(shí)現(xiàn)at模式的必要條件逻翁,在數(shù)據(jù)庫(kù)本地事務(wù)隔離級(jí)別 讀已提交(Read Committed) 或以上的基礎(chǔ)上,Seata(AT 模式)的默認(rèn)全局隔離級(jí)別是 讀未提交(Read Uncommitted) 捡鱼,通過 SELECT FOR UPDATE 語句實(shí)現(xiàn)讀已提交 八回。

6、總結(jié)

跟TCC事務(wù)模式對(duì)比AT自動(dòng)事務(wù)模式能帶來這些好處:

  1. 難度低
    AT模式 對(duì)于缺少分布式事務(wù)經(jīng)驗(yàn)的開發(fā)者來說,開發(fā)者僅按照傳統(tǒng)開發(fā)模式缠诅,通過簡(jiǎn)單的注解就可委托框架層補(bǔ)充實(shí)現(xiàn)整個(gè)分布式事務(wù)溶浴,甚至不需要了解分布式事務(wù)的原理。
  2. 效率高
    AT模式管引,開發(fā)者專注于業(yè)務(wù)sql士败,只需要加注解就可實(shí)現(xiàn)分布式事務(wù),而無需處理如TCC模式下的服務(wù)邏輯需拆分為try 褥伴、confirm和cancel三個(gè)部分谅将;因此,很大程度上可以提高開發(fā)效率重慢。
  3. 更安全
    拿TCC事務(wù)模型來說戏自,要求開發(fā)者將服務(wù)拆分為try 、confirm和cancel三個(gè)部分伤锚,同時(shí)還要求開發(fā)者自身有縝密的設(shè)計(jì)和嚴(yán)謹(jǐn)?shù)拇a來控制事務(wù)安全,應(yīng)對(duì)空回滾志衣、冪等屯援、懸掛等問題,并兼顧性能 念脯;而開發(fā)者對(duì)分布式事務(wù)的掌握程度不盡相同狞洋,自然實(shí)現(xiàn)的質(zhì)量也很難保證。

缺點(diǎn):

  1. 性能損耗
    前后兩次查詢绿店,以及與TC的RPC通信吉懊,以及undo_log的寫入,會(huì)增加更多的開銷假勿。
  2. 熱點(diǎn)數(shù)據(jù)
    全局鎖雖然是行鎖借嗽,但對(duì)熱點(diǎn)數(shù)據(jù)的讀寫依然不友好。

Seata AT和XA模式聯(lián)系和區(qū)別

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末转培,一起剝皮案震驚了整個(gè)濱河市恶导,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌浸须,老刑警劉巖惨寿,帶你破解...
    沈念sama閱讀 216,324評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異删窒,居然都是意外死亡裂垦,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門肌索,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蕉拢,“玉大人,你說我怎么就攤上這事∑罅浚” “怎么了测萎?”我有些...
    開封第一講書人閱讀 162,328評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)届巩。 經(jīng)常有香客問我硅瞧,道長(zhǎng),這世上最難降的妖魔是什么恕汇? 我笑而不...
    開封第一講書人閱讀 58,147評(píng)論 1 292
  • 正文 為了忘掉前任腕唧,我火速辦了婚禮,結(jié)果婚禮上瘾英,老公的妹妹穿的比我還像新娘枣接。我一直安慰自己,他們只是感情好缺谴,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,160評(píng)論 6 388
  • 文/花漫 我一把揭開白布但惶。 她就那樣靜靜地躺著,像睡著了一般湿蛔。 火紅的嫁衣襯著肌膚如雪膀曾。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,115評(píng)論 1 296
  • 那天阳啥,我揣著相機(jī)與錄音添谊,去河邊找鬼。 笑死察迟,一個(gè)胖子當(dāng)著我的面吹牛斩狱,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播扎瓶,決...
    沈念sama閱讀 40,025評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼所踊,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了栗弟?” 一聲冷哼從身側(cè)響起污筷,我...
    開封第一講書人閱讀 38,867評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎乍赫,沒想到半個(gè)月后瓣蛀,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,307評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡雷厂,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,528評(píng)論 2 332
  • 正文 我和宋清朗相戀三年惋增,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片改鲫。...
    茶點(diǎn)故事閱讀 39,688評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡诈皿,死狀恐怖林束,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情稽亏,我是刑警寧澤壶冒,帶...
    沈念sama閱讀 35,409評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站截歉,受9級(jí)特大地震影響胖腾,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜瘪松,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,001評(píng)論 3 325
  • 文/蒙蒙 一咸作、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧宵睦,春花似錦记罚、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至烟馅,卻和暖如春酵使,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背焙糟。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評(píng)論 1 268
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留样屠,地道東北人穿撮。 一個(gè)月前我還...
    沈念sama閱讀 47,685評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像痪欲,于是被迫代替她去往敵國(guó)和親悦穿。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,573評(píng)論 2 353

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