TCC(補償事務)
TCC 屬于目前比較火的一種柔性事務解決方案。TCC 這個概念最早誕生于數據庫專家帕特 · 赫蘭德(Pat Helland)于 2007 發(fā)表的 《Life beyond Distributed Transactions: an Apostate’s Opinion》 這篇論文,感興趣的小伙伴可以閱讀一下這篇論文。
三個階段
簡單來說,TCC 是 Try、Confirm、Cancel 三個詞的縮寫,它分為三個階段:
- Try(嘗試)階段 : 嘗試執(zhí)行
完成業(yè)務檢查,并預留好必需的業(yè)務資源。
- Confirm(確認)階段 :確認執(zhí)行
當所有事務參與者的 Try 階段執(zhí)行成功就會執(zhí)行 Confirm ,Confirm 階段會處理 Try 階段預留的業(yè)務資源。否則,就會執(zhí)行 Cancel 。
通常情況下,采用 TCC 則認為 Confirm 階段是不會出錯的。即:只要 Try 成功,Confirm 一定成功。若 Confirm 階段真的出錯了,需引入重試機制或人工處理。
- Cancel(取消)階段 :取消執(zhí)行,釋放 Try 階段預留的業(yè)務資源
通常情況下,采用 TCC 則認為 Cancel 階段也是一定成功的。若 Cancel 階段真的出錯了,需引入重試機制或人工處理。
TM 事務管理器
- TM 事務管理器可以實現為獨立的服務,也可以讓全局事務發(fā)起方充當 TM 的角色,TM 獨立出來是為了成為公共組件,是為了考慮系統結構和軟件復用
- TM 在發(fā)起全局事務時生成全局事務記錄,全局事務 ID 貫穿整個分布式事務調用鏈條,用來記錄事務上下文,追蹤和記錄狀態(tài),由于 Confirm 和 Cancel 失敗需要重試,因此需要實現冪等性,冪等性是指同一個操作無論請求多少次,其結果都相同
示例介紹
我們拿轉賬場景來說:
-
Try(嘗試)階段 : 在轉賬場景下,Try 要做的事情是就是檢查賬戶余額是否充足,預留的資源就是轉賬資金
-
Confirm(確認)階段 : 如果 Try 階段執(zhí)行成功的話,Confirm 階段就會執(zhí)行真正的扣錢操作
-
Cancel(取消)階段 :釋放 Try 階段預留的轉賬資金
一般情況下,當我們使用 TCC
模式的時候,需要自己實現 try
, confirm
, cancel
這三個方法,來達到最終一致性。也就是說,正常情況下會執(zhí)行 try
, confirm
,如下圖所示。
出現異常的話會執(zhí)行 try
, cancel
,如下圖所示。
因此,TCC 模式不需要依賴于底層數據資源的事務支持,但是需要我們手動實現更多的代碼,屬于 侵入業(yè)務代碼 的一種分布式解決方案。
針對 TCC 的實現,業(yè)界也有一些不錯的開源框架。不同的框架對于 TCC 的實現可能略有不同,不過大致思想都一樣。
-
ByteTCC : ByteTCC 是基于 Try-Confirm-Cancel(TCC)機制的分布式事務管理器的實現。 相關閱讀:關于如何實現一個 TCC 分布式事務框架的一點思考
-
Seata :Seata 是一款開源的分布式事務解決方案,致力于在微服務架構下提供高性能和簡單易用的分布式事務服務。
-
Hmily : 金融級分布式事務解決方案。
空回滾、冪等、懸掛
空回滾:
- 在沒調用 Try 方法的情況下,調用了第二階段的 Cancel 方法,Cancel 方法需要識別出這是一個空回滾,然后直接返回成功
- 出現原因是當一個分支事務所在服務宕機或網絡異常,分支事務調用記錄為失敗,這個時候其實是沒有執(zhí)行 Try 階段,當故障恢復后,分布式事務進行回滾則會調用第二階段的 Cacel 方法,從而形成空回滾
- 解決思路是關鍵就是要識別出這個空回滾。思路很簡單就是需要知道一階段是否執(zhí)行,如果執(zhí)行了,那就是正?;貪L。如果沒有執(zhí)行,那就是空回滾。前面已經說過 TM 在發(fā)起全局事務時生成全局事務記錄,全局事務 ID 貫穿整個分布式事務調用鏈條。再額外增加一張分支事務記錄表,其中有全局事務 ID 和分支事務 ID,第一階段 Try 方法里會插入一條記錄,表示一階段執(zhí)行了。Cancel 接口里讀取該記錄,如果該記錄存在,則正?;貪L;如果該記錄不存在,則是空回滾
冪等:文章來源:http://www.zghlxwxcb.cn/news/detail-431458.html
- 通過前面介紹已經了解到,為了保證 TCC 二階段提交重試機制不會引發(fā)數據不一致,要求 TCC 的二階段 Try、Confirm 和 Cancel 接口保證冪等,這樣不會重復使用或者釋放資源。如果冪等控制沒有做好,很有可能導致數據不一致等嚴重問題
- 解決思路在上述“分支事務記錄”中增加執(zhí)行狀態(tài),每次執(zhí)行前都查詢該狀態(tài)
懸掛:文章來源地址http://www.zghlxwxcb.cn/news/detail-431458.html
- 懸掛就是對于一個分布式事務,其二階段 Cancel 接口比 Try 接口先執(zhí)行
- 出現原因是在 RPC 調用分支事務 try 時,先注冊分支事務,再執(zhí)行 RPC 調用,如果此時 RPC 調用的網絡發(fā)生擁堵,通常 RPC 調用是有超時時間的,RPC 超時以后,TM 就會通知 RM 回滾該分布式事務,可能回滾完成后,RPC 請求才到達參與者真正執(zhí)行,而一個 Try 方法預留的業(yè)務資源,只有該分布式事務才能使用,該分布式事務第一階段預留的業(yè)務資源就再也沒有人能夠處理了,對于這種情況,我們就成為懸掛,即業(yè)務資源預留后沒法繼續(xù)處理
- 解決思路時候如果二階段執(zhí)行完成,那一階段就不能再繼續(xù)執(zhí)行。再執(zhí)行一階段事務時判斷在該全局事務下,“分支事務記錄”表中是否已經有二階段事務記錄,如果有則不執(zhí)行 Try
參考
- [JavaGuide]
- 分布式事務(三):分布式事務解決方案之TCC(Try、Confirm、Cancel)
- 分布式事務(五):分布式事務解決方案之最大努力通知
到了這里,關于分布式事務TCC 你真的理解了嗎的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!