在Seata的AT模式中,在服務執行完成後,直接進行RM提交和資源釋放,提供了對CAP理論相對平衡的解決方案,並且沒有侵入業務工程; ...
目錄
單個掉隊,導致集體被動擺爛;
一、業務背景
在分散式架構中,事務管理是個無法避開的複雜問題,雖然有多種解決方案,但是需要根據業務去選擇合適的;
從個人最近幾年的實踐經驗來看,Seata組件的AT模式比較常用,本文從實際的案例出發,來深入分析該模式的原理;
首先創建一個全局事務管理的介面,這裡是在Facade服務中開啟全局事務;
請求經過三個微服務,並且各個服務都進行數據源的操作,然後模擬鏈路成功和異常的情況,來分析不同狀態的邏輯實現;
二、Seata架構
1、核心組件
三大組件
- TC:事務協調者
即Transaction Coordinator,維護全局和分支事務的狀態,驅動全局事務提交或回滾。
- TM:事務管理器
即Transaction Manager,定義全局事務的範圍,開始事務、提交事務,回滾事務。
- RM:資源管理器
即Resource Manager,管理分支事務處理的資源,向TC註冊分支事務,報告分支事務的狀態,驅動分支事務提交或回滾。
基礎交互
TC是需要獨立部署的服務,TM和RM是集成在服務中,三大組件相互協作,共同完成分佈事務的管理;
2、AT模式
事務模型
AT是Seata預設的模式,需要基於支持本地ACID事務的關係型資料庫;Java應用,通過JDBC訪問資料庫;基於案例流程,先分析AT的事務模型;
2.1 TM負責定義全局事務的邊界,向TC申請,開啟一個全局事務;
2.2 全局事務創建成功後,生成全局唯一的XID;
2.3 XID會在微服務請求鏈路上下文中傳播;
2.4 RM向TC註冊分支事務,並歸屬到XID對應的全局事務進行調度;
2.5 TM向TC發起相應XID的全局事務提交或回滾決議;
2.6 TC完成對XID管理的全部分支事務提交或回滾的調度;
核心機制
執行階段:每個微服務的請求完成後,基於本地資料庫的事務能力,保證業務數據和回滾日誌在同一個本地事務中提交,快速釋放連接和對資源的鎖定;
完成階段:全局提交時分支事務已經完成提交,會清理回滾日誌,快速結束流程;全局回滾基於XID和BranchID查詢回滾日誌,完成數據回滾;
數據源代理
在AT模式中,應用需要使用Seata組件中的JDBC代理數據源DataSourceProxy,實現對真正目標數據源的代理訪問;
三、案例分析
1、流程分析
案例的簡單描述
在案例中涉及三個服務,Facade服務開啟全局事務,然後分別請求Account和Quartz服務的更新介面,通過Quartz介面是否拋異常來調試AT模式的原理;
從實際的請求執行來說,絕大多數的請求都是可以執行成功的,而AT模式的非同步化提交極大限度的顧及全局事務的效率問題,少數失敗的情況也可以通過回滾日誌進行反向補償;
2、寫隔離
上述流程分析AT模式的原子性,即多個分支事務要麼都成功要麼都失敗,接下來分析多個事務中的全局鎖隔離機制,先看寫隔離,假設TX1先開始;
TX1邏輯
- TX1開始本地事務,拿到本地鎖,然後執行更新操作;
- TX1本地事務提交前,需要先獲取全局鎖,否則無法提交;
- TX1獲取全局鎖並提交,釋放本地鎖,但未釋放全局鎖;
TX2邏輯
- TX2此時開始本地事務,拿到本地鎖;
- TX2執行本地事務提交前,嘗試獲取全局鎖;
- 由於全局鎖被TX1持有,TX2會重試等待全局鎖;
假設TX1全局提交
- TX1如果全局事務提交,會釋放全局鎖;
- TX2獲取全局鎖成功,執行本地事務提交;
假設TX1全局回滾
- TX1如果全局事務回滾,要重新獲取數據的本地鎖,進行回滾的補償動作;
- TX2如果仍在等待全局鎖,並且還持有本地鎖,TX1事務回滾失敗,會不斷的重試;
- 當TX2等待全局鎖超時,會放棄全局鎖並回滾本地事務,釋放本地鎖;
- TX1最終獲取數據的本地鎖,完成回滾動作;
在該過程中,TX1在結束前一直持有全局鎖,TX2獲取不到全局鎖無法對相同的數據執行更新動作,所以避免了臟寫的問題;
3、讀隔離
在資料庫本地隔離級別為讀已提交或以上的基礎上,Seata的AT模式預設全局隔離級別是讀未提交;如果需要全局的讀已提交,可以通過SELECT FOR UPDATE
語句的代理;
該語句的執行也需要獲取全局鎖,如果全局鎖被TX1持有,TX2會釋放本地鎖,查詢會被阻塞併進行重試,拿到全局鎖讀取成功後返回;
四、對比XA模式
XA是一個分散式事務分段提交協議;事務管理器即TM:作為全局事務的調度者,負責整個事務中本地資源的提交和回滾;本地資源管理器即RM:大部分關係型資料庫都實現了XA介面;
TM先向所有的參與事務的RM發送確認請求,根據確認的結果,判斷是調用RM的commit提交還是rollback回滾;
XA具有強一致性,在2段提交的過程中,會持有資源的鎖,如果是在交易下單等複雜鏈路中,並且併發量很高,會存在長事務風險,XA無法滿足該類高併發的場景;
而在Seata的AT模式中,在服務執行完成後,直接進行RM提交和資源釋放,提供了對CAP理論相對平衡的解決方案,並且沒有侵入業務工程;
五、參考源碼
應用倉庫:
https://gitee.com/cicadasmile/butte-flyer-parent
組件封裝:
https://gitee.com/cicadasmile/butte-frame-parent
Gitee主頁: https://gitee.com/cicadasmile/butte-java-note