Spring Cloud Alibaba分布式事務(wù)解決框架Seata概念入門篇
Seata中文參考文檔: http://seata.io/zh-cn/docs/overview/what-is-seata.html
前言
繼上一篇文章 分布式事務(wù)解決方案及理論基礎(chǔ)入門 介紹了分布式解決方案相關(guān)概念之后,本篇給大家?guī)鞸pring Cloud Alibaba開源的一款分布式解決方案框架Seata,本篇為Seata組件的相關(guān)概念介紹,如果想使用Seata實(shí)戰(zhàn)解決分布式事務(wù)難題還請(qǐng)看下一篇文章。
一、什么是微服務(wù)架構(gòu)
“微服務(wù)架構(gòu)是一種架構(gòu)模式,它提倡將單一應(yīng)用程序劃分成一組小的服務(wù),服務(wù)之間相互協(xié)調(diào)、互相配合,為用戶提供最終價(jià)值。每個(gè)服務(wù)運(yùn)行在其獨(dú)立的進(jìn)程中,服務(wù)和服務(wù)之間采用輕量級(jí)的通信機(jī)制相互溝通(通常是基于HTTP的Restful API).每個(gè)服務(wù)都圍繞著具體的業(yè)務(wù)進(jìn)行構(gòu)建,并且能夠被獨(dú)立的部署到生產(chǎn)環(huán)境、類生產(chǎn)環(huán)境等。另外,應(yīng)盡量避免統(tǒng)一的、集中的服務(wù)管理機(jī)制,對(duì)具體的一個(gè)服務(wù)而言,應(yīng)根據(jù)業(yè)務(wù)上下文,選擇合適的語言、工具對(duì)其進(jìn)行構(gòu)建"
二、分布式事務(wù)的產(chǎn)生
1. 單體架構(gòu)
一個(gè)用戶完整的下單過程,在單體應(yīng)用中,只需要一個(gè)在一個(gè)項(xiàng)目中,一個(gè)數(shù)據(jù)庫(kù)里,通過調(diào)用下下單接口,下單時(shí)調(diào)用扣減庫(kù)存方法和扣減賬戶余額來完成一筆訂單。
2. 分布式架構(gòu)
單體應(yīng)用被拆分成微服務(wù)應(yīng)用,原來的三個(gè)模塊被拆分成三個(gè)獨(dú)立的應(yīng)用,分別使用不同的數(shù)據(jù)源,在業(yè)務(wù)操作上需要調(diào)用三個(gè)服務(wù)來完成。此時(shí)每個(gè)服務(wù)內(nèi)部的數(shù)據(jù)一致性由本地事務(wù)來保證,但是全局的數(shù)據(jù)一致性問題沒法保證,分布式事務(wù)由此產(chǎn)生。
三、Seata的4種事務(wù)模式
1. Seata是什么
Seata 是一款開源的分布式事務(wù)解決方案,致力于提供高性能和簡(jiǎn)單易用的分布式事務(wù)服務(wù)。Seata 將為用戶提供了 AT、TCC、SAGA 和 XA 事務(wù)模式,默認(rèn)使用AT模式,為用戶打造一站式的分布式解決方案。
2. AT 模式
前提
- 基于支持本地 ACID 事務(wù)的關(guān)系型數(shù)據(jù)庫(kù)。
- Java 應(yīng)用,通過 JDBC 訪問數(shù)據(jù)庫(kù)。
整體機(jī)制
通過2PC兩階段提交協(xié)議的演變:
- 一階段: 業(yè)務(wù)數(shù)據(jù)和回滾日志記錄在同一個(gè)本地事務(wù)中提交,釋放本地鎖和連接資源。
- 二階段: 提交異步化,成功則批量地刪除相應(yīng)回滾日志記錄,失敗則通過回滾日志進(jìn)行反向補(bǔ)償。
寫隔離
- 1)、 一階段本地事務(wù)提交前,需要確保先拿到全局鎖。
- 2)、拿不到全局鎖,不能提交本地事務(wù);拿到全局鎖,提交本地事務(wù)并插入undo_log記錄。
- 3)、拿全局鎖的嘗試被限制在一定范圍內(nèi),超出范圍將放棄,并根據(jù)undo_log記錄回滾本地事務(wù),釋放本地鎖。
讀隔離
1)、在數(shù)據(jù)庫(kù)本地事務(wù)隔離級(jí)別 讀已提交(Read Committed) 或以上的基礎(chǔ)上,Seata(AT 模式)的默認(rèn)全局隔離級(jí)別是 讀未提交(Read Uncommitted)。
理解: 在全局事務(wù)提交之前,本地事務(wù)會(huì)先提交,這時(shí)候查詢數(shù)據(jù),對(duì)于本地庫(kù)是Read Committed,對(duì)于全局來說是 Read Uncommitted。
2)、如果要求全局的讀已提交,目前 Seata 的方式是通過 SELECT FOR UPDATE 語句的代理。
3. TCC模式
TCC不依賴 RM 對(duì)分布式事務(wù)的支持,而是通過對(duì)業(yè)務(wù)邏輯的分解來實(shí)現(xiàn)分布式事務(wù)。
- 1)、初步操作 Try: 完成所有業(yè)務(wù)檢查,預(yù)留必須的業(yè)務(wù)資源。
- 2)、確認(rèn)操作 Confirm: 真正執(zhí)行的業(yè)務(wù)邏輯,不做任何業(yè)務(wù)檢查,只使用 Try 階段預(yù)留的業(yè)務(wù)資源。因此,只要 Try 操作成功,Confirm 必須能成功。另外,Confirm 操作需滿足冪等性,保證一筆分布式事務(wù)能且只能成功一次。
- 3)、取消操作 Cancel: 釋放 Try 階段預(yù)留的業(yè)務(wù)資源。同樣的,Cancel 操作也需要滿足冪等性。
所謂 TCC 模式,是指支持把 自定義 的分支事務(wù)納入到全局事務(wù)的管理中。
4. SAGA模式
概述
Seata提供的長(zhǎng)事務(wù)解決方案,在Saga模式中,業(yè)務(wù)流程中每個(gè)參與者都提交本地事務(wù),當(dāng)出現(xiàn)某一個(gè)參與者失敗則補(bǔ)償前面已經(jīng)成功的參與者,一階段正向服務(wù)和二階段補(bǔ)償服務(wù)都由業(yè)務(wù)開發(fā)實(shí)現(xiàn)。

適用場(chǎng)景:
- 業(yè)務(wù)流程長(zhǎng)、業(yè)務(wù)流程多
- 參與者包含其它公司或遺留系統(tǒng)服務(wù),無法提供 TCC 模式要求的三個(gè)接口
優(yōu)勢(shì):
- 一階段提交本地事務(wù),無鎖,高性能
- 事件驅(qū)動(dòng)架構(gòu),參與者可異步執(zhí)行,高吞吐
- 補(bǔ)償服務(wù)易于實(shí)現(xiàn)
缺點(diǎn):
不保證隔離性
基于狀態(tài)機(jī)引擎的 Saga 實(shí)現(xiàn)。
目前SEATA提供的Saga模式是基于狀態(tài)機(jī)引擎來實(shí)現(xiàn)的,機(jī)制是:
- 通過狀態(tài)圖來定義服務(wù)調(diào)用的流程并生成 json 狀態(tài)語言定義文件。
- 狀態(tài)圖中一個(gè)節(jié)點(diǎn)可以是調(diào)用一個(gè)服務(wù),節(jié)點(diǎn)可以配置它的補(bǔ)償節(jié)點(diǎn)。
- 狀態(tài)圖 json 由狀態(tài)機(jī)引擎驅(qū)動(dòng)執(zhí)行,當(dāng)出現(xiàn)異常時(shí)狀態(tài)引擎反向執(zhí)行已成功節(jié)點(diǎn)對(duì)應(yīng)的補(bǔ)償節(jié)點(diǎn)將事務(wù)回滾,異常發(fā)生時(shí)是否進(jìn)行補(bǔ)償也可由用戶自定義決定。
- 可以實(shí)現(xiàn)服務(wù)編排需求,支持單項(xiàng)選擇、并發(fā)、子流程、參數(shù)轉(zhuǎn)換、參數(shù)映射、服務(wù)執(zhí)行狀態(tài)判斷、異常捕獲等功能。
示例狀態(tài)圖:

5. XA 模式
前提
- 支持XA 事務(wù)的數(shù)據(jù)庫(kù)。
- Java 應(yīng)用,通過 JDBC 訪問數(shù)據(jù)庫(kù)。
整體機(jī)制
在 Seata 定義的分布式事務(wù)框架內(nèi),利用事務(wù)資源(數(shù)據(jù)庫(kù)、消息服務(wù)等)對(duì) XA 協(xié)議的支持,以 XA 協(xié)議的機(jī)制來管理分支事務(wù)的一種 事務(wù)模式。

執(zhí)行階段:
- 可回滾:業(yè)務(wù) SQL 操作放在 XA 分支中進(jìn)行,由資源對(duì) XA 協(xié)議的支持來保證 可回滾
- 持久化:XA 分支完成后,執(zhí)行 XA prepare,同樣,由資源對(duì) XA 協(xié)議的支持來保證 持久化(即,之后任何意外都不會(huì)造成無法回滾的情況)
完成階段:
- 分支提交:執(zhí)行 XA 分支的 commit
- 分支回滾:執(zhí)行 XA 分支的 rollback
關(guān)于XA模式的介紹這里先簡(jiǎn)單提一下,更詳細(xì)的信息查閱 :http://seata.io/zh-cn/docs/dev/mode/xa-mode.html
四、Seata模型介紹
Seata的整個(gè)過程模型如下圖所示:
上圖中主要有三種角色:
- TM:事務(wù)管理者,用來告訴 TC,全局事務(wù)的開始,提交,回滾。
- TC:事務(wù)協(xié)調(diào)者,即seata-server,維護(hù)全局事務(wù)和分支事務(wù)的狀態(tài),通知各RM提交或者回滾。
- RM:資源管理者,每一個(gè) RM 都會(huì)作為一個(gè)分支事務(wù)注冊(cè)在 TC,負(fù)責(zé)分支事務(wù)的注冊(cè)、提交和回滾。
術(shù)語介紹:
- XID - Transaction ID ,一個(gè)分布式事務(wù)唯一一個(gè)ID。
- TC - 事務(wù)協(xié)調(diào)者,維護(hù)全局和分支事務(wù)的狀態(tài),驅(qū)動(dòng)全局事務(wù)提交或回滾。
- TM - 事務(wù)管理器,定義全局事務(wù)的范圍:開始全局事務(wù)、提交或回滾全局事務(wù)。
- RM - 資源管理器,管理分支事務(wù)處理的資源,與TC交談以注冊(cè)分支事務(wù)和報(bào)告分支事務(wù)的狀態(tài),并驅(qū)動(dòng)分支事務(wù)提交或回滾。
典型的分布式事務(wù)處理流程包括以下步驟:
- TM向TC請(qǐng)求開啟一個(gè)全局事務(wù),TC給TM返回一個(gè)全局事務(wù)的XID,即XID;
- XID在微服務(wù)調(diào)用鏈路的上下文間傳播;
- RM向TC注冊(cè)分支事務(wù),將其納入XID對(duì)應(yīng)全局事務(wù)的管轄;
- TM根據(jù)XID向TC發(fā)出提交或者回滾的請(qǐng)求;
- TC根據(jù)XID使RM提交或者回滾
流程圖如下:

五、關(guān)于Seata架構(gòu)
早在2019年,阿里開源了分布式事務(wù)框架Seata,原名叫Fescar,后來跟螞蟻TCC方案整合后改名為Seata,截止目前2020年11月3日,Seata已經(jīng)更新到v1.4.0版本了,雖然在之前的版本發(fā)布中,存在一些潛在的問題,但是通過開源團(tuán)隊(duì)快速修復(fù)問題,并且快速迭代發(fā)布新版本之下,目前相對(duì)較穩(wěn)定。
同時(shí)相比與其它分布式事務(wù)框架,Seata架構(gòu)的亮點(diǎn)主要有幾個(gè):
- 應(yīng)用層基于SQL解析實(shí)現(xiàn)了自動(dòng)補(bǔ)償,從而最大程度的降低業(yè)務(wù)侵入性;
- 將分布式事務(wù)中TC(事務(wù)協(xié)調(diào)者)獨(dú)立部署,負(fù)責(zé)事務(wù)的注冊(cè)、回滾;
- 通過全局鎖實(shí)現(xiàn)了寫隔離與讀隔離。
六、參考文檔
Seata中文官方文檔: http://seata.io/zh-cn/docs/overview/what-is-seata.html
Seata-Server下載地址: https://github.com/seata/seata/releases
分布式事務(wù)Demo: https://github.com/seata/seata-samples
Seata源碼地址: https://github.com/seata/seataSeata中文參考文檔: http://seata.io/zh-cn/docs/overview/what-is-seata.html