分布式事务的解决思路与方案
導航
- 一、事務的種類與場景
- 二、分布式事務解決方案
- 2.1 全局事務
- 2.2 可靠消息事務
- 2.3 最大努力通知
- 2.4 TCC 事務
- 三、TCC 模式常見問題
- 3.1 二階段冪等
- 3.2 空回滾
- 3.3 資源懸掛
一、事務的種類與場景
本地事務實際上就是指數據庫的事務,參考《MySQL —— 事務與隔離級別總結》
分布式事務指的是在分布式環境下,由多個本地事務組成,多個系統之間如何保證事務之間的原子性、一致性等問題。例如多個系統訪問同一個數據庫,多個系統訪問多個數據庫,等等這些場景,都數據分布式事務的討論范圍。
二、分布式事務解決方案
介紹四個業界應用比較廣泛的分布式解決方案:全局事務、可靠消息服務、最大努力通知、TCC事務(補償型事務)。
2.1 全局事務
全局事務基于DTP 模型實現,這是由X/Open 組織提出的一種分布式事務模型,全稱為“分布式事務處理參考模型”。
DTP規定要實現分布式事務,需要三種角色:
AP:Application 應用系統
TM:Transaction Manager 事務管理器
RM:Resource Manager 資源管理器
在 DTP 模型中,整個系統的事務分為兩個階段,即 2PC(2 Phrase Commit):
1、準備階段:也可以叫表決階段或投票階段。TM 向 各個 AP 發送準備命令,并告訴各本地事務即將提交事務。TM同步等待參與者的響應。此階段各本地事務已經完成了事務邏輯,就差一步提交操作。
2、提交階段:TM 根據響應結果,決定發送提交或回滾命令。若都準備成功,則提交事務;但只要有一個返回失敗,就全部回滾。
全局事務的優缺點:
優點:由于是同步阻塞協議,因此可以保證數據的強一致性。資源管理器本身就是數據庫,實現不需要增加太多的代碼邏輯,實現成本低。流程簡單。
缺點:
1、單點故障問題:TM 是全局事務的協調者、管理者,絕不能出現單點故障問題。
2、同步阻塞:增加了資源阻塞時間,可能存在死鎖的風險,需要增加超時機制。
3、一致性問題:二階段提交可能存在失敗的情況,導致數據不一致。
總之,該模型是旨在保證強一致性的全局事務模型,但由于其模型仍然簡單粗糙,在實際生產中,還需要進一步擴展和細化。
2.2 可靠消息事務
基于可靠消息服務的方案是通過消息中間件保證上、下游應用數據操作的一致性。基本可以理解為就是 RocketMQ提供的事務消息,參考《Spring Cloud —— RocketMQ 的消息類型》
假設有A和B兩個系統,分別可以處理任務A和任務B。此時存在一個業務流程,需要將任務A和任務B在同一個事務中處理,就可以使用消息中間件來實現這種分布式事務。
2.3 最大努力通知
最大努力通知也被稱為定期校對,其實是對可靠消息事務方案的進一步優化。它引入了本地消息表來記錄錯誤消息,然后加入失敗消息的定期校對功能,來進一步保證消息會被下游系統消費。
這種方案由于本身需要引入許多額外的補償結構,如本地消息表、失敗消息表、定期校對者等等,增加了業務耦合度,提高了實現復雜度,因此在業界并不是特別流行,但不得不說的確是增加了系統事務的安全性降低了事故風險。
第一步:消息由A系統投遞到中間件
1、處理業務的同一事務中,向本地消息表中寫入一條記錄
2、準備專門的消息發送者,輪詢本地消息表,將需要發送的(未發送的或失敗的)事務消息發送到中間件
第二步:消息由中間件投遞到B系統
1、消息中間件收到消息后負責將該消息同步投遞到下游系統,并觸發下游系統的任務執行
2、當下游系統處理成功后,向消息中間件反饋確認應答,消息中間件便可以將該消息刪除,表示該事務完成
3、如果投遞失敗,增加重試機制,對重試失敗的,寫入錯誤消息表
4、消息中間件需要提供失敗消息的回查接口,下游系統會定期查詢失敗消息,自行消費。
優點:一種非常經典的分布式事務解決方案,最大限度保證最終一致性。
缺點:消息表會耦合到業務系統中,如果沒有封裝好的解決方案,會有很多雜活需要處理。
2.4 TCC 事務
TCC 即為 Try Confirm Cancel,它屬于補償型分布式事務,業務層面的分布式事務。其中:
Try:指的是預留,即資源的預留和鎖定。
Confirm:確認,其實就是真正的執行提交。
Cancel:撤銷,就是回滾、撤銷鎖定動作。
同樣,TCC模型也有一個全局的管理者或協調者角色,用來記錄TCC全局事務狀態,并提交或回滾事務。
TCC模型的難點在于業務上的定義,對每一個操作都需要定義三個動作分別對應 try-confirm-cancel例如,預留操作,需要明確預留或鎖定的業務資源。因此TCC是業務耦合型分布式事務,需要根據特定的場景和業務邏輯來設計相應的操作。另外,確認或撤銷操作可能需要重試,因此需要保證操作的冪等。
TCC相較于2PC、3PC,其優點在于可以跨數據庫,跨業務來實現事務,但缺點也顯而易見,就是開發量大,業務耦合度高。
TCC 兩階段提交與 XA 兩階段提交的區別:
XA 是資源層面的分布式事務,強一致性,在兩階段提交的整個過程中,會一直持有資源的鎖。
TCC 是業務層面的分布式事務,最終一致性,不會一直持有資源的鎖。
三、TCC 模式常見問題
TCC分布式事務模式其實屬于2PC的一種。其本身仍然存在一些繞不開的問題。
3.1 二階段冪等
由于網絡抖動,分布式事務框架可能會重復調用同一分布式事務中的一個分支事務的二階段方法(comfirm或cancel)。
所以分支事務的二階段接口必須要保證冪等性,否則會產生資源的重復使用或重復釋放從而影響業務。
對于冪等類型的問題,通常的手段是引入冪等查詢。例如,可以通過增加一張事務狀態表,包含如下幾個關鍵字段:
1.主事務id
2.分支事務id,與主事務id作為聯合主鍵,唯一標識一筆分支事務。
3.分支事務狀態:init(1),confirmed(2),rollbacked(3)
冪等記錄的插入時機是參與者的Try 方法,此時的分支事務狀態會被初始化為 init。然后當二階段的 comfirm/canel 執行時會將其狀態置為 comfirmed/rollbacked。
當TC重復調用二階段接口時,參與者會先獲取事務狀態控制表對應的記錄查看其事務狀態。如果狀態已為終態(confirmed或rollbacked),則直接將結果返回給TC,幫助其推進分布式事務,時序圖如下:
3.2 空回滾
空回滾指的是,在未收到 Try 請求的情況下收到 Cancel 請求。
如果不對空回滾加以防范的話,可能會造成資源的無效釋放,即在沒有預留資源的情況下就釋放資源,造成故障。
針對空回滾,使用事務狀態控制表同樣有效。
當 Try 方法被成功執行后,會插入一條分支事務記錄,當后續二階段的 Cancel 方法執行時,如果記錄存在且狀態為 INIT,就表示一階段已成功執行,可以正常執行回滾,釋放預留資源;如果記錄不存在則表示一階段未執行,本次為空回滾,不釋放任何資源。
一般情況下,是應用是需要允許空回滾的。
3.3 資源懸掛
資源懸掛,意思是一階段Try 由于網絡超時或阻塞等原因,在二階段Cancel(Try超時事務管理器要Cancel全局事務)之后執行,即 Cancel --> Try,造成服務或資源懸掛。
可以看到,資源懸掛的前提是空回滾。因為一階段Try超時,事務管理器必須執行回滾操作,這就造成了參與者一定會先收到 Cancel ,即空回滾。
視實際業務場景而定,一般會允許空回滾的情況,但要避免懸掛。可以在空回滾后,向事務狀態控制表中插入一條 狀態為 ROLLBACKED 的分支事務記錄,然后在 Try 的時候要增加對冪等的處理(可以依賴于數據庫的唯一約束),這樣,由于網絡原因而超時的 Try 請求就會自動失敗,從而放棄調本次TCC事務。
總結
以上是生活随笔為你收集整理的分布式事务的解决思路与方案的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: js将object转化为json数据,j
- 下一篇: 基本农田卫星地图查询_发现谷歌地图替代网