如何解決分布式事務(wù)問題?

結(jié)論:真實(shí)業(yè)務(wù)場景中,很少用到強(qiáng)一致場景,可靠消息、最大努力通知使用的相對(duì)較多,涉及一些 RPC 場景,也可以考慮 TCC 方案。

方案 一致性 隔離性 并發(fā) 業(yè)務(wù)成本 技術(shù)成本 靈活度 代碼侵入 開源項(xiàng)目 適用場景
2PC (XA協(xié)議) 強(qiáng)一致性 需要設(shè)置數(shù)據(jù)隔離級(jí)別為SERIALIZABLE,將導(dǎo)致吞退嚴(yán)重 無,數(shù)據(jù)庫原生支持 幾乎無 Seata AT 不推薦
可靠消息 最終一致性 高并發(fā),但整體性能取決于可靠消息系統(tǒng),一般會(huì)有限流保障 低,實(shí)現(xiàn)事務(wù)狀態(tài)反查 高,可靠消息系統(tǒng)的研發(fā) RocketMQ
Qmq
Mafka
下游結(jié)果不影響上游執(zhí)行的異步流程
最大努力通知 最終一致性 高并發(fā),基本不影響整體性能 低,通知方提供查詢補(bǔ)償能力 基本無 - 業(yè)務(wù)執(zhí)行結(jié)果的通知
Saga 最終一致性 高并發(fā),狀態(tài)驅(qū)動(dòng) 中低,需要提供逆向方法 Seata Saga 流程節(jié)點(diǎn)多且長
TCC 最終一致性 Try保障隔離性 高并發(fā) Seata TCC
EasyTransaction
ByteTCC
Swan
各種同步場景
1、談下 TCC 及在業(yè)務(wù)中的使用?
  • 概念介紹:TCC 的全稱是 Try、Confirm、Cancel的縮寫,是兩階段提交的一種實(shí)現(xiàn),其中 Try對(duì)應(yīng)第 1 階段的準(zhǔn)備操作,Confirm對(duì)應(yīng)第 2 階段的提交操作,Cancel對(duì)應(yīng)第 2 階段的回滾操作。之所以起一個(gè)新名字,是因?yàn)門CC需要使用者自定義業(yè)務(wù)邏輯。在微服務(wù)架構(gòu)中比較常見,Try、Confirm、Cancel分別對(duì)應(yīng) 1 次微服務(wù)調(diào)用。
  • 應(yīng)用案例: 參考 TCC 思路,實(shí)現(xiàn)了一個(gè)類似的。1.調(diào)撥服務(wù)調(diào)用庫存服務(wù)鎖定庫存(Try)。鎖定庫存后,創(chuàng)建初始狀態(tài)的調(diào)撥單,并把調(diào)撥消息通知倉庫服務(wù)。 2.倉庫服務(wù)創(chuàng)建出庫單,出庫時(shí),通知調(diào)撥服務(wù)已出庫。 3.1 調(diào)撥服務(wù)提交庫存確認(rèn)(Confirm)、更改調(diào)撥單狀態(tài)。 3.2 如果無法出庫或業(yè)務(wù)取消調(diào)撥,會(huì)解鎖庫存(Cancel)。
  • 注意事項(xiàng):若Try階段失敗,則調(diào)撥單創(chuàng)建失?。蝗鬋onfirm或Cancel階段失敗,需要正向重試直到成本。調(diào)撥服務(wù)需要做數(shù)據(jù)最終一致性監(jiān)控,即對(duì)比調(diào)撥量、庫存量、出庫量三者是否一致,不一致時(shí)觸發(fā)修復(fù)預(yù)案或人工介入。
  • 三階段提交和二階段提交的區(qū)別在于,首先在第一步進(jìn)行可用資源校驗(yàn)。XA 事務(wù)是二階段提交理論具象化后的一個(gè)具體標(biāo)準(zhǔn)。
2、談下 SAGA 及在業(yè)務(wù)中的使用?
  • 概念介紹:每個(gè) Saga 由一系列 sub-transaction Ti (子事務(wù)、也叫分支事務(wù))組成,每個(gè) Ti 都有對(duì)應(yīng)的補(bǔ)償動(dòng)作 Ci,補(bǔ)償動(dòng)作用于撤銷 Ti 造成的結(jié)果??梢钥吹剑?TCC 相比,Saga 沒有“資源預(yù)留”動(dòng)作,它的 Ti 就是直接提交到庫。Saga 事務(wù)的執(zhí)行順序有兩種:
    (正常情況下,一階段流程)T1, T2, T3, ..., Tn
    (異常情況下,一階段 + 補(bǔ)償流程)T1, T2, ..., Tj, Cj,..., C2, C1,其中 0 < j <= n

  • Saga 定義了兩種恢復(fù)策略:
    backward recovery,逆序回滾:即上面提到的第二種執(zhí)行順序,其中 j 是發(fā)生錯(cuò)誤的 sub-transaction,這種做法的效果是撤銷掉之前所有成功的 sub-transation,使得整個(gè) Saga 的執(zhí)行結(jié)果撤銷。
    forward recovery,向前重試:適用于必須要成功的場景,執(zhí)行順序是類似于這樣的:T1, T2, ..., Tj (失敗), Tj (重試),..., Tn,其中 j 是發(fā)生錯(cuò)誤的 sub-transaction,該情況下不需要 Ci。

  • 場景示例:


    image.png
image.png
image.png
  • 注意事項(xiàng):正向重試失敗后,需要做逆向回滾,若逆向回滾失敗,需重試和修復(fù)預(yù)案例。
3、可靠消息-基于事務(wù)消息方案
image.png
4、可靠消息-基于本地日志表

整體設(shè)計(jì)思路:上游業(yè)務(wù)操作本地?cái)?shù)據(jù)庫時(shí),會(huì)開啟一個(gè)本地事務(wù),對(duì)業(yè)務(wù)數(shù)據(jù)進(jìn)行修改,在同一事務(wù)中,往提前創(chuàng)建好的Swan事務(wù)日志表中插入一條記錄。此時(shí)對(duì)業(yè)務(wù)數(shù)據(jù)的修改和事務(wù)日志表的插入要么同時(shí)成功,要么同時(shí)失敗。事務(wù)執(zhí)行成功后,發(fā)送MQ消息或者RPC調(diào)用,收到明確成功ack后,刪除事務(wù)日志。同消息隊(duì)列事務(wù)消息方案類似,客戶端會(huì)啟動(dòng)一個(gè)兜底線程掃描未刪除的事務(wù)日志,重復(fù)發(fā)起調(diào)用直到成功,然后后刪除事務(wù)日志。

image.png
5、最大努力通知
  • 上游系統(tǒng)(生產(chǎn)計(jì)劃服務(wù))執(zhí)行完成業(yè)務(wù)邏輯后,通知給下游系統(tǒng)(庫內(nèi)加工服務(wù));同時(shí)提供反查接口,供下游系統(tǒng)數(shù)據(jù)一致性校驗(yàn)處理
  • 下游系統(tǒng)根據(jù)通知,做業(yè)務(wù)邏輯處理(如進(jìn)行商品庫內(nèi)加工)
  • 為防止上游系統(tǒng)丟消息,下游系統(tǒng)會(huì)定時(shí)反查上游系統(tǒng),做兜底修復(fù)。與可靠消息的區(qū)別是,誰來保證最終一致性。

參考文檔:
https://www.sofastack.tech/blog/sofa-meetup-3-seata-retrospect/

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容