1. 程式人生 > >架構設計 | 基於電商交易流程,圖解TCC事務分段提交

架構設計 | 基於電商交易流程,圖解TCC事務分段提交

本文原始碼:[GitHub·點這裡](https://github.com/cicadasmile/data-manage-parent) || [GitEE·點這裡](https://gitee.com/cicadasmile/data-manage-parent) # 一、場景案例簡介 ## 1、場景描述 分散式事務在業務系統中是十分常見的,最經典的場景就是電商架構中的交易業務,如圖: ![](https://img2020.cnblogs.com/blog/1691717/202008/1691717-20200831105710082-1750298134.png) 客戶端通過請求訂單服務,執行下單操作,實際上從訂單服務上又觸發了多個服務鏈請求,基本步驟如下: - 客戶端請求在訂單服務上建立訂單; - 訂單服務呼叫賬戶服務扣款; - 訂單服務呼叫庫存服務執行庫存扣減; - 訂單通過物流服務,轉化為物流運單; 這套流程在電商系統中是基本業務,在實際的開發中遠比這裡描述的複雜。 ## 2、服務時序圖 上述1中是業務性的流程概念描述,從系統開發層面,在微服務的架構模式下,通常的時序流如下: ![](https://img2020.cnblogs.com/blog/1691717/202008/1691717-20200831105722755-625965585.png) 這樣服務間的通訊時序圖在程式設計中十分常見,在分散式系統中,清楚的描述各個服務間的通訊流程是十分關鍵的。 上圖描述的交易流程是在最理想的狀態下,各個服務都執行成功,但是程式是不能100%保證一直正常,經常出現如下情況: - 服務間通訊失敗; - 單個節點服務宕掉; - 服務介面執行失敗; 這些都是實際開發中經常出現的問題,比如訂單建立成功,扣款成功,但是庫存扣減失敗,物流運單生成,那麼這筆訂單該如何處理?這就是分散式事務要解決的核心問題。 分散式事務機制要保證不同服務之間形成一個整體性的可控的事務,業務流程上的服務除非全部成功,否則任何服務的操作失敗,都會導致所有服務上操作回滾,撤銷已經完成的動作。 # 二、TCC基礎概念 ## 1、分段提交協議 XA是一個分散式事務協議,大致分為兩部分:事務管理器和本地資源管理器,本地資源管理器基本由資料庫實現,大多數關係型資料庫都實現XA介面,而事務管理器作為全域性事務的排程者,負責整個事務中本地資源的提交和回滾,基本原理如下: ![](https://img2020.cnblogs.com/blog/1691717/202008/1691717-20200831105740254-53829220.png) **階段1:事務詢問** 事務管理器向所有的參與事務的資源管理器傳送確認請求,詢問是否可以執行事務提交操作,並等待各參與者的響應,如果執事務操作成功,就反饋給事務管理器表示事務可以執行,如果沒有成功執行事務,就反饋事務不可以執行; **階段2:事務提交** XA根據第一階段每個資源管理器是否都準備提交成功,判斷是要事務整體提交還是回滾,正式執行事務提交操作,並在完成提交之後釋放整個事務佔用的資源;事務也會存在失敗情況,導致流程取消回滾; XA事務具有強一致性,在兩階段提交的整個過程中,一直會持有資源的鎖,效能不理想的缺點很明顯,特別是在交易下單鏈路中,往往併發量很高,XA無法滿足該類高併發場景。 ## 2、TCC概念簡介 Try(預處理)-Confirm(確認)-Cancel(取消)模式的簡稱TCC。 **Try階段** 業務檢查(一致性)及資源預留(隔離),該階段是一個初步操作,提交事務前的檢查及預留業務資源完成;例如購票系統中的佔位成功,需要在15分鐘內支付; **Confirm階段** 確認執行業務操作,不在執行任何業務檢查,基於Try階段預留的業務資源,從理想狀態下看只要Try成功,Confirm也會成功,因為資源的檢查和鎖定都已經成功;該階段出現問題,需要重試機制或者手動處理;購票系統中的佔位成功並且15分鐘內支付完成,購票成功; **Cancel階段** Cancel階段是在業務執行錯誤需要回滾到狀態下執行分支事務的取消,預留資源的釋放;購票系統中的佔位成功但是15分鐘內沒有支付,取消佔位; ## 3、TCC對比XA XA事務的強一致性,導致資源層的鎖定; TCC在業務層面追求最終一致性,不會長久佔用資源; # 三、分段事務分析 現在回到模組一中的場景案例,在理想狀態下流程全部成功是好的,但實際情況是突發情況很多,基於TCC模式分析上述電商的具體業務: ## 1、資源預留 在TCC模式下,通常表字段的狀態設計思路為:訂單(支付中.已支付.取消訂單),賬戶(金額.凍結金額),庫存(庫存.凍結庫存),物流(出庫中.已出庫,已撤回),這種狀態管理在開發中非常常見。 所以在TCC模式裡通常會如下處理資源預留: ![](https://img2020.cnblogs.com/blog/1691717/202008/1691717-20200831105759719-31438752.png) 假設訂單總額為:200,狀態:支付中,則此時資源預留情況如下: - tc_account賬戶表:tc_total=1000,tc_ice=200,總金額1000,凍結200; - tc_inventory庫存表:tc_total=100,tc_ice=20,總庫存100件,凍結20件; - tc_waybill運單表:tc_state=1,運單狀態,出庫中; 這樣下單鏈路上的相關資源已檢查並且預留成功; ## 2、資源提交確認 資源預留成功之後,執行資源提交執行: ![](https://img2020.cnblogs.com/blog/1691717/202008/1691717-20200831105812014-1632847788.png) - tc_account賬戶表:tc_total=800,tc_ice=0,即訂單扣款成功; - tc_inventory庫存表:tc_total=80,tc_ice=0,庫存消減成功; - tc_waybill運單表:tc_state=2,運單狀態,已出庫; 這樣下單鏈路上的相關資源已全部提交處理成功,這是最理想的狀態; ## 3、失敗回滾 整個過程是可能執行失敗的,或者使用者直接自己發起回退,則要回滾整個鏈路上的資料: ![](https://img2020.cnblogs.com/blog/1691717/202008/1691717-20200831105824388-476861481.png) - tc_account賬戶表:tc_total=1000,tc_ice=0,取消賬戶凍結的200; - tc_inventory庫存表:tc_total=100,tc_ice=0,取消庫存凍結的20件; - tc_waybill運單表:tc_state=3,運單狀態,已撤回; 這樣下單鏈路上的相關資料都基於該筆訂單做回退操作,恢復; ## 4、補償機制 整個電商交易流程,不管是成功,還是完整的回退失敗,都是需要在理想狀態下,要求整個服務鏈路和資料是絕對正常的才行。但是在實際分散式架構下是很難保證的,所以在產品的設計上會預留很多操作入口,用來手動做事務補償或回退操作: ![](https://img2020.cnblogs.com/blog/1691717/202008/1691717-20200831105835840-1427150929.png) 大型複雜的業務系統中,直接修改資料庫通常情況下是不允許的,一般核心流程會預留各種操作入口,用來處理突發狀況,彌補資料的完整性,例如交易鏈路上,只要扣款成功,後續的資料無論如何都會補上,是不允許回滾的,當然如果沒有扣款成功,訂單有效期結束,該筆交易也就算做結束。 ## 5、寫在最後 通過電商交易的案例,和TCC模式的概念,描述了分散式事務的流程和處理思路,在開發時通常會選擇現有的分散式元件來具體實現事務控制,這個流程後續再聊。 # 四、原始碼地址 ``` GitHub·地址 https://github.com/cicadasmile/data-manage-parent GitEE·地址 https://gitee.com/cicadasmile/data-manage-parent ``` ![](https://img2020.cnblogs.com/blog/1691717/202008/1691717-20200811231321146-174169065.png) **推薦閱讀:架構設計** |序號| 標題| |:---|:---| |00 | [架構設計:單服務.叢集.分散式,基本區別和聯絡](https://mp.weixin.qq.com/s/NGxI3rC-6mWMDnrClaOR3Q)| |01 | [架構設計:分散式業務系統中,全域性ID生成策略](https://mp.weixin.qq.com/s/1TKAwr99rKEHSxqXFixEhQ)| |02 | [架構設計:分散式系統排程,Zookeeper叢集化管理](https://mp.weixin.qq.com/s/Yr4A95poVjlFsQ-Q0dF7hA)| |03 | [架構設計:介面冪等性原則,防重複提交Token管理](https://mp.weixin.qq.com/s/o9sxN6GwxdNYTKZvRexwjg)| |04 | [架構設計:快取管理模式,監控和記憶體回收策略](https://mp.weixin.qq.com/s/jBu-OZ69DbXfmdIf5VC7kQ)| |05 | [架構設計:非同步處理流程,多種實現模式詳解](https://mp.weixin.qq.com/s/RQm1vPJak0rCGW8dll4oAA)| |06 | [架構設計:高併發流量削峰,共享資源加鎖機制](https://mp.weixin.qq.com/s/T13aak6us7ZF36qooQ-YPQ)| |07 | [架構設計:分散式服務,庫表拆分模式詳解](https://mp.weixin.qq.com/s/EZCIgZ4EWvFKgKlCYej68g)| |08 | [架構設計:分散式事務①概念簡介和基礎理論](https://mp.weixin.qq.com/s/7ppTArAcu_i8ENa-t