分布式事務的一致性問題
1 場景
-
服務1 調(diào)用 服務2 的接口(比如 HTTP / gRPC);
-
服務2 修改自己的數(shù)據(jù)并返回成功;
-
服務1 收到服務2返回結(jié)果后,繼續(xù)修改自己數(shù)據(jù)庫;
-
? 如果服務1 此時數(shù)據(jù)庫操作失敗(例如網(wǎng)絡(luò)、SQL異常等),就會導致:
-
服務2 的數(shù)據(jù)已經(jīng)修改;
-
服務1 的數(shù)據(jù)沒改成功;
-
出現(xiàn)服務間數(shù)據(jù)不一致問題
2 解決方案
1. 本地事務 + 可靠消息最終一致性(推薦)
流程如下:
-
服務1先修改本地數(shù)據(jù),把需要通知服務2的消息寫入“消息表”(或發(fā)送消息到MQ);
-
提交本地事務;
-
然后異步發(fā)送消息給服務2(由消息中間件或定時任務發(fā)出);
-
服務2收到消息后修改自己的數(shù)據(jù);
-
若失敗可重試、補償,保證最終一致性。
?? 典型架構(gòu):微服務 + 消息隊列(如 RabbitMQ、Kafka、RocketMQ)
? 優(yōu)點:無強依賴,易落地
?? 缺點:不是強一致,而是最終一致性2. 分布式事務協(xié)議(SAGA 長事務 補償操作)
SAGA 模式:
假如你用一個 SAGA 引擎(比如 DTM、Seata),你會定義事務步驟和補償接口:
框架自動控制流程:
如果 deduct_balance 失敗了,自動倒序執(zhí)行:
refund_balance → restore_inventory → cancel_order
如果 restore_inventory 失敗了,也可以重試;
整個事務狀態(tài)持久化,有日志、有可視化界面
基于 DTM(分布式事務管理器)實現(xiàn) SAGA 模式的實際例子,使用 Flask + Python
前提準備 安裝 DTM:
你可以用 Docker 啟動:
36789 是 gRPC 端口(不需要可以忽略)
8080 是 HTTP 事務管理接口
安裝 Python 客戶端:
3. 寫反向補償邏輯(手動回滾)
服務1在失敗后,嘗試調(diào)用服務2進行“撤銷”操作;
例如刪除、恢復原狀態(tài);
必須要求服務2提供回滾接口;

浙公網(wǎng)安備 33010602011771號