Spring Cloud Alibaba(六励堡、分布式事務Seata)

Seata 是什么

Seata 是一款開源的分布式事務解決方案谷丸,致力于提供高性能和簡單易用的分布式事務服務。Seata 將為用戶提供了 AT应结、TCC刨疼、SAGA 和 XA 事務模式,為用戶打造一站式的分布式解決方案鹅龄。

什么是分布式事務問題

  1. 單體應用
    單體應用中揩慕,一個業(yè)務操作需要調用三個模塊完成,此時數據的一致性由本地事務來保證扮休。


    單體應用單一數據庫使用本地事務
  2. 微服務應用
    隨著業(yè)務需求的變化迎卤,單體應用被拆分成微服務應用,原來的三個模塊被拆分成三個獨立的應用玷坠,分別使用獨立的數據源止吐,業(yè)務操作需要調用三個服務來完成。此時每個服務內部的數據一致性由本地事務來保證侨糟,但是全局的數據一致性問題沒法保證碍扔。


    微服務多數據源

總結:
在微服務架構中由于全局數據一致性沒法保證產生的問題就是分布式事務問題。簡單來說秕重,一次業(yè)務操作需要操作多個數據源或需要進行遠程調用不同,就會產生分布式事務問題。

分布式事務處理過程的三個組件

Transaction Coordinator (TC): 事務協調器溶耘,維護全局事務的運行狀態(tài)二拐,負責協調并驅動全局事務的提交或回滾;可以理解為Seata凳兵。
Transaction Manager (TM): 控制全局事務的邊界百新,負責開啟一個全局事務,并最終發(fā)起全局提交或全局回滾的決議庐扫;可以理解為@GlobalTransaction注解饭望。
Resource Manager (RM): 控制分支事務,負責分支注冊形庭、狀態(tài)匯報铅辞,并接收事務協調器的指令,驅動分支(本地)事務的提交和回滾萨醒≌迳海可以理解為MySQL數據庫。

分布式事務執(zhí)行過程

  1. TM 向 TC 申請開啟一個全局事務富纸,全局事務創(chuàng)建成功并生成一個全局唯一的 XID囤踩;
  2. XID 在微服務調用鏈路的上下文中傳播旨椒;
  3. RM 向 TC 注冊分支事務,將其納入 XID 對應全局事務的管轄堵漱;
  4. TM 向 TC 發(fā)起針對 XID 的全局提交或回滾決議综慎;
  5. TC 調度 XID 下管轄的全部分支事務完成提交或回滾請求。
    分布式事務執(zhí)行過程

四種事務模式

Seata 目標打造一站式的分布事務的解決方案怔锌,最終會提供四種事務模式:

  • AT 模式:參見《Seata AT 模式》文檔
  • TCC 模式:參見《Seata TCC 模式》文檔
  • Saga 模式:參見《SEATA Saga 模式》文檔
  • XA 模式:正在開發(fā)中...
    目前使用的流行度情況是:AT > TCC > Saga寥粹。因此,我們在學習 Seata 的時候埃元,可以花更多精力在 AT 模式上涝涤,最好搞懂背后的實現原理,畢竟分布式事務涉及到數據的正確性岛杀,出問題需要快速排查定位并解決阔拳。

AT 模式

前提
  1. 基于支持本地 ACID 事務的關系型數據庫。
  2. Java 應用类嗤,通過 JDBC 訪問數據庫糊肠。
整體機制
  1. 一階段:業(yè)務數據和回滾日志記錄在同一個本地事務中提交,釋放本地鎖和連接資源遗锣。
  2. 二階段:
    提交異步化货裹,非常快速地完成精偿。
    回滾通過一階段的回滾日志進行反向補償弧圆。
工作機制

以一個示例來說明整個 AT 分支的工作過程。

業(yè)務表:product

Field Type Key
id bigint(20) PRI
name varchar(100)
since varchar(100)

AT 分支事務的業(yè)務邏輯:
update product set name = 'GTS' where name = 'TXC';

一階段

過程:

  1. 解析 SQL:得到 SQL 的類型(UPDATE)笔咽,表(product)搔预,條件(where name = 'TXC')等相關的信息。
  2. 查詢前鏡像:根據解析得到的條件信息叶组,生成查詢語句拯田,定位數據。
    select id, name, since from product where name = 'TXC';
  3. 得到前鏡像:
id name since
1 TXC 2014
  1. 執(zhí)行業(yè)務 SQL:更新這條記錄的 name 為 'GTS'甩十。
  2. 查詢后鏡像:根據前鏡像的結果船庇,通過主鍵定位數據。
    select id, name, since from product where id = 1;`
  3. 得到后鏡像:
id name since
1 GTS 2014
  1. 插入回滾日志:把前后鏡像數據以及業(yè)務 SQL 相關的信息組成一條回滾日志記錄枣氧,插入到 UNDO_LOG 表中溢十。
{
    "branchId": 641789253,
    "undoItems": [{
        "afterImage": {
            "rows": [{
                "fields": [{
                    "name": "id",
                    "type": 4,
                    "value": 1
                }, {
                    "name": "name",
                    "type": 12,
                    "value": "GTS"
                }, {
                    "name": "since",
                    "type": 12,
                    "value": "2014"
                }]
            }],
            "tableName": "product"
        },
        "beforeImage": {
            "rows": [{
                "fields": [{
                    "name": "id",
                    "type": 4,
                    "value": 1
                }, {
                    "name": "name",
                    "type": 12,
                    "value": "TXC"
                }, {
                    "name": "since",
                    "type": 12,
                    "value": "2014"
                }]
            }],
            "tableName": "product"
        },
        "sqlType": "UPDATE"
    }],
    "xid": "xid:xxx"
}
  1. 提交前,向 TC 注冊分支:申請 product 表中达吞,主鍵值等于 1 的記錄的 全局鎖 。
  2. 本地事務提交:業(yè)務數據的更新和前面步驟中生成的 UNDO LOG 一并提交荒典。
  3. 將本地事務提交的結果上報給 TC酪劫。
二階段-回滾
  1. 收到 TC 的分支回滾請求吞鸭,開啟一個本地事務,執(zhí)行如下操作覆糟。
  2. 通過 XID 和 Branch ID 查找到相應的 UNDO LOG 記錄刻剥。
  3. 數據校驗:拿 UNDO LOG 中的后鏡與當前數據進行比較,如果有不同滩字,說明數據被當前全局事務之外的動作做了修改造虏。這種情況,需要根據配置策略來做處理麦箍,詳細的說明在另外的文檔中介紹漓藕。
  4. 根據 UNDO LOG 中的前鏡像和業(yè)務 SQL 的相關信息生成并執(zhí)行回滾的語句:
    update product set name = 'TXC' where id = 1;
  5. 提交本地事務。并把本地事務的執(zhí)行結果(即分支事務回滾的結果)上報給 TC挟裂。
二階段-提交
  1. 收到 TC 的分支提交請求享钞,把請求放入一個異步任務的隊列中,馬上返回提交成功的結果給 TC诀蓉。
  2. 異步任務階段的分支提交請求將異步和批量地刪除相應 UNDO LOG 記錄栗竖。

延伸閱讀:

  1. Spring Cloud Alibaba (6.1 Seata部署)

  2. Spring Cloud Alibaba (6.2 Seata 純 Spring Boot AT 模式 + 多數據源)

  3. Spring Cloud Alibaba (6.3 Seata 純 Spring Boot AT 模式 + HttpClient 遠程調用)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市渠啤,隨后出現的幾起案子狐肢,更是在濱河造成了極大的恐慌,老刑警劉巖沥曹,帶你破解...
    沈念sama閱讀 219,589評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件份名,死亡現場離奇詭異,居然都是意外死亡架专,警方通過查閱死者的電腦和手機同窘,發(fā)現死者居然都...
    沈念sama閱讀 93,615評論 3 396
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來部脚,“玉大人想邦,你說我怎么就攤上這事∥酰” “怎么了丧没?”我有些...
    開封第一講書人閱讀 165,933評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長锡移。 經常有香客問我呕童,道長,這世上最難降的妖魔是什么淆珊? 我笑而不...
    開封第一講書人閱讀 58,976評論 1 295
  • 正文 為了忘掉前任夺饲,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘往声。我一直安慰自己擂找,他們只是感情好,可當我...
    茶點故事閱讀 67,999評論 6 393
  • 文/花漫 我一把揭開白布浩销。 她就那樣靜靜地躺著贯涎,像睡著了一般。 火紅的嫁衣襯著肌膚如雪慢洋。 梳的紋絲不亂的頭發(fā)上塘雳,一...
    開封第一講書人閱讀 51,775評論 1 307
  • 那天,我揣著相機與錄音普筹,去河邊找鬼败明。 笑死,一個胖子當著我的面吹牛斑芜,可吹牛的內容都是我干的肩刃。 我是一名探鬼主播,決...
    沈念sama閱讀 40,474評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼杏头,長吁一口氣:“原來是場噩夢啊……” “哼盈包!你這毒婦竟也來了?” 一聲冷哼從身側響起醇王,我...
    開封第一講書人閱讀 39,359評論 0 276
  • 序言:老撾萬榮一對情侶失蹤呢燥,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后寓娩,有當地人在樹林里發(fā)現了一具尸體叛氨,經...
    沈念sama閱讀 45,854評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,007評論 3 338
  • 正文 我和宋清朗相戀三年棘伴,在試婚紗的時候發(fā)現自己被綠了寞埠。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,146評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡焊夸,死狀恐怖仁连,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情阱穗,我是刑警寧澤饭冬,帶...
    沈念sama閱讀 35,826評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站揪阶,受9級特大地震影響昌抠,放射性物質發(fā)生泄漏。R本人自食惡果不足惜鲁僚,卻給世界環(huán)境...
    茶點故事閱讀 41,484評論 3 331
  • 文/蒙蒙 一炊苫、第九天 我趴在偏房一處隱蔽的房頂上張望裁厅。 院中可真熱鬧,春花似錦劝评、人聲如沸姐直。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,029評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至撞叽,卻和暖如春姻成,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背愿棋。 一陣腳步聲響...
    開封第一講書人閱讀 33,153評論 1 272
  • 我被黑心中介騙來泰國打工科展, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人糠雨。 一個月前我還...
    沈念sama閱讀 48,420評論 3 373
  • 正文 我出身青樓才睹,卻偏偏與公主長得像,于是被迫代替她去往敵國和親甘邀。 傳聞我的和親對象是個殘疾皇子琅攘,可洞房花燭夜當晚...
    茶點故事閱讀 45,107評論 2 356