天天看點

架構設計 | 基于電商交易流程,圖解TCC事務分段送出一、場景案例簡介二、TCC基礎概念三、分段事務分析

一、場景案例簡介

1、場景描述

分布式事務在業務系統中是十分常見的,最經典的場景就是電商架構中的交易業務,如圖:

架構設計 | 基于電商交易流程,圖解TCC事務分段送出一、場景案例簡介二、TCC基礎概念三、分段事務分析

用戶端通過請求訂單服務,執行下單操作,實際上從訂單服務上又觸發了多個服務鍊請求,基本步驟如下:

  • 用戶端請求在訂單服務上建立訂單;
  • 訂單服務調用賬戶服務扣款;
  • 訂單服務調用庫存服務執行庫存扣減;
  • 訂單通過物流服務,轉化為物流運單;

這套流程在電商系統中是基本業務,在實際的開發中遠比這裡描述的複雜。

2、服務時序圖

上述1中是業務性的流程概念描述,從系統開發層面,在微服務的架構模式下,通常的時序流如下:

架構設計 | 基于電商交易流程,圖解TCC事務分段送出一、場景案例簡介二、TCC基礎概念三、分段事務分析

這樣服務間的通信時序圖在程式設計中十分常見,在分布式系統中,清楚的描述各個服務間的通信流程是十分關鍵的。

上圖描述的交易流程是在最理想的狀态下,各個服務都執行成功,但是程式是不能100%保證一直正常,經常出現如下情況:

  • 服務間通信失敗;
  • 單個節點服務宕掉;
  • 服務接口執行失敗;

這些都是實際開發中經常出現的問題,比如訂單建立成功,扣款成功,但是庫存扣減失敗,物流運單生成,那麼這筆訂單該如何處理?這就是分布式事務要解決的核心問題。

分布式事務機制要保證不同服務之間形成一個整體性的可控的事務,業務流程上的服務除非全部成功,否則任何服務的操作失敗,都會導緻所有服務上操作復原,撤銷已經完成的動作。

二、TCC基礎概念

1、分段送出協定

XA是一個分布式事務協定,大緻分為兩部分:事務管理器和本地資料總管,本地資料總管基本由資料庫實作,大多數關系型資料庫都實作XA接口,而事務管理器作為全局事務的排程者,負責整個事務中本地資源的送出和復原,基本原理如下:

架構設計 | 基于電商交易流程,圖解TCC事務分段送出一、場景案例簡介二、TCC基礎概念三、分段事務分析

階段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模式裡通常會如下處理資源預留:

架構設計 | 基于電商交易流程,圖解TCC事務分段送出一、場景案例簡介二、TCC基礎概念三、分段事務分析

假設訂單總額為: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、資源送出确認

資源預留成功之後,執行資源送出執行:

架構設計 | 基于電商交易流程,圖解TCC事務分段送出一、場景案例簡介二、TCC基礎概念三、分段事務分析
  • tc_account賬戶表:tc_total=800,tc_ice=0,即訂單扣款成功;
  • tc_inventory庫存表:tc_total=80,tc_ice=0,庫存消減成功;
  • tc_waybill運單表:tc_state=2,運單狀态,已出庫;

這樣下單鍊路上的相關資源已全部送出處理成功,這是最理想的狀态;

3、失敗復原

整個過程是可能執行失敗的,或者使用者直接自己發起回退,則要復原整個鍊路上的資料:

架構設計 | 基于電商交易流程,圖解TCC事務分段送出一、場景案例簡介二、TCC基礎概念三、分段事務分析
  • tc_account賬戶表:tc_total=1000,tc_ice=0,取消賬戶當機的200;
  • tc_inventory庫存表:tc_total=100,tc_ice=0,取消庫存當機的20件;
  • tc_waybill運單表:tc_state=3,運單狀态,已撤回;

這樣下單鍊路上的相關資料都基于該筆訂單做回退操作,恢複;

4、補償機制

整個電商交易流程,不管是成功,還是完整的回退失敗,都是需要在理想狀态下,要求整個服務鍊路和資料是絕對正常的才行。但是在實際分布式架構下是很難保證的,是以在産品的設計上會預留很多操作入口,用來手動做事務補償或回退操作:

架構設計 | 基于電商交易流程,圖解TCC事務分段送出一、場景案例簡介二、TCC基礎概念三、分段事務分析

大型複雜的業務系統中,直接修改資料庫通常情況下是不允許的,一般核心流程會預留各種操作入口,用來處理突發狀況,彌補資料的完整性,例如交易鍊路上,隻要扣款成功,後續的資料無論如何都會補上,是不允許復原的,當然如果沒有扣款成功,訂單有效期結束,該筆交易也就算做結束。

5、寫在最後

通過電商交易的案例,和TCC模式的概念,描述了分布式事務的流程和處理思路,在開發時通常會選擇現有的分布式元件來具體實作事務控制,這個流程後續再聊。