1 背景
市面上常見的有,2pc/3pc、tcc、saga等常見的分散式事務解決方案,但是實際實施起來框架比較重,設計開發比較繁瑣,不易於快速開發上手。本文提供一種基於柔性事務設計的簡單易上手的分散式事務設計方案,用於解決常見的分散式事務常見場景。
2 常見分散式事務場景
2.1 同步場景
常見的場景,方法內依賴外部微服務多個同步介面,等同步介面返回再展開後續邏輯,如下圖1描述。
圖1 分散式事務同步場景
存在的問題:B/C失敗後,A/B不能回滾,造成資料不一致?
2.2 非同步場景
方法內依賴外部微服務多個同步介面同時,本地事務提交併發出非同步MQ,如下圖2描述。
圖2 分散式事務非同步場景
存在的問題:詢價系統無法保證本地事務和mq訊息的傳送同時成功或失敗,會造成資料不一致。
3 解決方案
3.1 資料模型設計
事務表:記錄每次同步方法執行的狀態,包括:1-進行中(同步方法執行開始)、2-已完成(同步方法執行成功)、3-失敗(同步方法執行失敗)、4-已回滾(回滾方法執行成功);
方法呼叫表:記錄一個完整的事務內所有方法的執行前入參、同步方法介面、回滾介面、回滾入參、方法執行順序,如下圖3描述:
圖3 事務服務資料模型
3.2 設計原理
原理:一個完整事務內,1.首先每個方法提供回滾介面,其次,事務內每次同步方法執行時,優先維護入引數據到事務表,方便後續做回滾補償;2.整個事務內某一個方法執行失敗時,結束整個事務,並更新事務表狀態=失敗;3.事務表透過輪詢狀態status=3(失敗)事務,呼叫回滾介面,利用回滾入參進行介面補償;4.回滾邏輯:找到事務表中失敗的執行方法的順序值,只呼叫小於失敗順序值的所有回滾介面、入參,注意並不回滾失敗值的介面,並根據順序倒序進行介面回滾補償。
圖4 回滾原理圖
3.3 執行時序
圖5 回滾執行時序圖
3.4 回滾失敗處理方案:
- 事務服務的高可用保障:柔性事務前提是保證事務服務高可用性,重點保障;
- 回滾服務重試機制:回滾介面失敗重試機制,保證資料一致性;
- 為了避免架構複雜度,做日誌記錄、報警、人工處理。
4 注意問題
- 回滾服務的冪等性:回滾做好業務防重和系統防重,防止因為回滾帶來的業務資料不一致;
- 髒資料:整個事務中某一方法執行失敗,前面呼叫方法的資料作為髒資料使用。簡單的解決方案:依賴事務表整個事務執行狀態來決定能否使用髒資料。但缺點就是這樣會耦合業務邏輯;
- 中心化:整個事務的維護完全依賴事務服務完成,需要保證事務服務的高可用性;
- 實時性:事務維護本方案透過定時任務維護,如果業務場景有實時性要求,方式可以改為:在整個事務中某一方法執行失敗時,catch異常,catch內更新任務狀態成功時,直接進行回滾邏輯呼叫。
5 總結
除了透過常規本地大事務保證事務完整性方案,本次方案提供了一套基於柔性事務回滾補償的方式來保證分散式事務,透過維護事務服務和事務服務中心對應資料表,從而保障整個分散式事務的完整性。實現方式簡單、輕量、易於操作,方便地解決了常見的分散式事務場景。
作者:鄭朋輝