分布式事務(wù)的解決方案—Seata AT模式
Seata是一款開源的分布式事務(wù)解決方案的框架,它致力于在微服務(wù)架構(gòu)下提供高性能和簡單易用的分布式事務(wù)服務(wù),Seata為用戶提供了AT、TCC、SAGA和XA事務(wù)模式。其中AT模式(auto transaction)是一種無侵入的分布式事務(wù)解決方案,AT模式的核心思想是基于二階段提交實現(xiàn)的。
1、二階段提交
兩階段提交協(xié)議(Two-Phase Commit,2PC)是一種分布式事務(wù)處理協(xié)議,目的是在確保多個分布式系統(tǒng)中執(zhí)行的事務(wù)能夠在所有參與者中保持一致性。2PC協(xié)議通過將事務(wù)的提交過程分為兩個階段來實現(xiàn)確保即使在出現(xiàn)故障的情況下,也能保持?jǐn)?shù)據(jù)的一致。2PC的實現(xiàn)過程如下所示:
圖片
第一階段:表決階段
(1)事務(wù)協(xié)調(diào)者向所有參與者(Participants)發(fā)送準(zhǔn)備請求,詢問它們是否能夠提交事務(wù)
(2)每個參與者收到請求后,檢查其本地的事務(wù)狀態(tài),確保它能夠完成操作。如果參與者準(zhǔn)備好提交,它會將其狀態(tài)更改為“準(zhǔn)備提交(Prepared)”并返回一個“準(zhǔn)備好”響應(yīng)給協(xié)調(diào)者。如果無法提交,參與者會返回“拒絕”響應(yīng)。
表決階段中所有參與者都不會將數(shù)據(jù)更改持久化到數(shù)據(jù)庫中,而是保留在一個臨時狀態(tài)。
第二階段:執(zhí)行階段
(1)事務(wù)協(xié)調(diào)者收到了所有參與者的“準(zhǔn)備好"響應(yīng),它會向所有參與者發(fā)送提交請求,告知參與者可以安全地將更改寫入數(shù)據(jù)庫
(2)參與者收到提交請求后,將更改持久化到數(shù)據(jù)庫并返回提交確認(rèn)給事務(wù)協(xié)調(diào)者。
(3)如果事務(wù)協(xié)調(diào)者收到所有參與者的提交確認(rèn),它會宣布事務(wù)提交成功。如果有任何參與者拒絕提交,協(xié)調(diào)者會發(fā)送回滾請求,要求所有參與者回滾之前的操作。
2PC優(yōu)點的具有簡單易理解(協(xié)議流程較為簡單,易于實現(xiàn)和理解)、保證數(shù)據(jù)的一致性(所有參與者對于事務(wù)的提交或回滾保持一致)。同時它的缺點也很明顯,如阻塞(協(xié)調(diào)者崩潰時會導(dǎo)致參與者阻塞,無法繼續(xù)處理事務(wù))、性能問題(2PC需要多次網(wǎng)絡(luò)往返,可能影響性能)、故障恢復(fù)復(fù)雜(處理參與者或協(xié)調(diào)者崩潰后的恢復(fù)機制比較復(fù)雜)。
2、Seata-AT模式
Seata-AT模式幾個角色TC、TM、RM,這幾個角色的概念如下所示:
(1)TC【事務(wù)協(xié)調(diào)器】
它是獨立的組件,需要獨立部署運行,Seata提供了這個獨立運行的程序,它負責(zé)維護全局事務(wù)的運行狀態(tài),接收TM指令發(fā)起全局事務(wù)的提交與回滾,負責(zé)與RM通信,協(xié)調(diào)各個分支事務(wù)的提交或回滾。
(2)TM【事務(wù)管理器】
TM需要嵌入應(yīng)用程序,它負責(zé)開啟一個全局事務(wù),并定義全局事務(wù)的范圍,TM目的是最終向TC發(fā)起全局提交或回滾指令。
(3)RM【資源管理器】
RM與TC通信,控制分支事務(wù),負責(zé)分支注冊、報告分支事務(wù)狀態(tài),并接收事務(wù)協(xié)調(diào)器TC的指令,命令分支事務(wù)完成本地事務(wù)的提交或回滾。
通過TC、TM、RM的的相互協(xié)調(diào)配合實現(xiàn)了分布式事務(wù)的處理,Seata-AT模式的實現(xiàn)原理圖如下所示:
圖片
TM負責(zé)定義全局事務(wù)的邊界,然后向TC申請開啟一個全局事務(wù),全局事務(wù)創(chuàng)建成功后會生成全局唯一的XID,這個XID會在微服務(wù)請求鏈路上下文中傳播。
Seata-AT模式的第一階段的工作:
(1)通過攔截和解析業(yè)務(wù)sql,然后根據(jù)解析sql語句中的條件生成查詢前的sql語句,將查詢結(jié)果當(dāng)做快照后保存起來,后續(xù)如果事務(wù)回滾直接根據(jù)快照數(shù)據(jù)生成反向sql進行回滾操作。
(2)Seata實現(xiàn)了JDBC協(xié)議,業(yè)務(wù)與數(shù)據(jù)庫交互首先要經(jīng)過Seata,這樣Seata對sql進行了攔截與處理,處理完成后將sql發(fā)送到真實數(shù)據(jù)庫執(zhí)行。
由于上述操作在同一個本地事務(wù)中,那么數(shù)據(jù)庫的事務(wù)特性保證數(shù)據(jù)的一致性。
Seata-AT模式的第二階段工作:
對于AT模式,二階段提交主要是將每個事務(wù)的參與者的快照數(shù)據(jù)刪除,同時釋放行鎖;如果回滾,利用快照數(shù)據(jù)執(zhí)行回滾。
在AT模式中,需要使用Seata組件中的JDBC代理數(shù)據(jù)源DataSourceProxy,實現(xiàn)對真正目標(biāo)數(shù)據(jù)源的代理訪問,通過代理實現(xiàn)攔截、解析sql的執(zhí)行來實現(xiàn)快照數(shù)據(jù)的保存,如果業(yè)務(wù)執(zhí)行成功,那么就刪除快照數(shù)據(jù),如果業(yè)務(wù)執(zhí)行失敗就使用快照回滾。