上一次我們講解了分布式事務的 2PC、3PC 。那么這次我們來理一下 TCC 事務。本次還是講解 TCC 的原理跟 .NET 其實沒有關系。
TCC
- Try 准備階段,嘗試執行業務
- Confirm 完成業務
- Cancel 回滾准備階段的業務
TCC 事務其實是 2PC 的一個擴展。上一次我們說了 2PC ,在二階段進行事務提交。因為 2PC 基本上是利用數據庫的
事務能力進行 commit ,其實這里還有可能出現一種 rollback 情況。 TCC 就是把 2PC 的二階段細化了,拆分成了 Confirm 跟 Cancel 兩個步驟。TCC 是 2PC 的一次進化,TCC 拆分二階段后已經不局限於數據庫事物了,它可以適用於非數據庫事物的場景。因為我們的 Cancel 階段可以進行更加復雜的回滾能力,業務補償能力。TCC 可以認為是業務層面的2PC 。
下面我們以使用客戶積分兌換房間為示例說明一下 TCC 事務。
- Try
為完成 TCC 事務的 Try 階段,我們需要在房間上增加一個狀態字段“是否鎖定”,一旦鎖定,其它訂單就沒有辦法預定這間房間。同樣我們需要在用戶積分表上增加一個字段“凍結積分”,如果涉及到並發可能要單獨拉一張表出來。這里簡化一點就加個字段吧。
Try階段開始:訂單服務把房間設置為鎖定狀態;積分服務把用戶的積分減去消耗的積分同時把消耗的積分暫存在凍結字段上。 - Confirm
如果一階段都提交成功了,那么所有的服務都開始進入 Confirm 階段。訂單服務把房間狀態更改為“已預定”狀態;積分服務把凍結的積分清0。這樣整個事務都成功完成了。 - Cancel
如果一階段某個服務沒有 Try 成功,那么所有的服務都要進入Cancel階段。比如訂單服務鎖定房源成功了,積分凍結的時候失敗了,那么訂單服務要進入 Cancel 階段,把房間的的鎖定狀態取消,從新釋放出來。如果鎖定房源失敗了,積分扣減成功了,那么 Cancel 階段就要把扣減的積分給加回去。
TCC 的一些問題
異常
如果 Confirm 階段出現異常,TCC 管理器會不斷的重試這個階段,直到成功。因為理論上認為只要 Try 是成功的,那么 Confirm 階段一定會成功。因為所需要的資源已經在 Try 階段凍結了。如果 Cancel 階段出現異常,那么 TCC 管理器也會不斷的重試這個階段來解除凍結的資源。
冪等
因為 TCC 有重試機制,所以所有的接口都需要實現冪等,避免多次調用對業務數據產生錯誤。比如多次扣款,多次下訂單等。
並發問題
因為 TCC 事務在 Try 階段對資源是完全的提交狀態,並沒有像 2PC 那樣使用數據庫事物來對資源進行鎖定,所以在並發的時候對資源的修改要格外注意。在處理業務的時候要時刻注意鎖定的資源對業務造成的一影響。
允許空取消
TCC 事務在一階段 Try 的時候失敗要運行進行 Cancel 提交。這時候 Cancel 其實是不需要做任何補償操作,我們稱之為空取消。這個時候也要注意,在編寫 Cancel 操作的時候要時刻注意到底有沒有完成 Try 操作,如果沒有完成 Try 操作則要進行空取消。
預防懸掛
TCC 按流程上來說是不會出現懸掛情況的。但是有一種特殊情況會造成資源的懸掛。按照正常流程我們的 Try 階段總是先於 Cancel 執行的。但是由於網絡擁堵的問題造成 Try 調用延遲了,TCC 管理器在一定時間沒收到 Try 成功響應后會發送 Cancel 調用,這個 Cancel 就有可能在 Try 之前先被調用了。在 Cancel 執行成功后, 這個 Try 請求調用才到達服務,這個時候如果 Try 被執行成功,那么就會造成資源的懸掛。所以當編寫 Try 代碼的時候同意需要注意是不是已經調用過 Cancel 操作了。
總結
TCC 事務是 2PC 的一種升級。TCC 相對於 2PC 不再依賴於本地數據庫事物能力,它可以使用於應用層面的事務。它把 2PC 的提交跟回滾操作明確的抽象成 Confirm 跟 Cancel 。TCC 事務在邏輯上是比較清晰的。但是 TCC 使用起來也有不方便的地方,就是它對代碼入侵比較強,比較繁瑣。每個業務都要強制拆分成3個方法。而且還要還要注意冪等,空取消,懸掛等問題。
相關文章
NET Core with 微服務 - 什么是微服務
.Net Core with 微服務 - 架構圖
.Net Core with 微服務 - Ocelot 網關
.Net Core with 微服務 - Consul 注冊中心
.Net Core with 微服務 - Seq 日志聚合
.Net Core with 微服務 - Elastic APM
.Net Core with 微服務 - Consul 配置中心
.Net Core with 微服務 - Polly 熔斷降級
.Net Core with 微服務 - 分布式事務 - 2PC、3PC