轉載本文需註明出處:微信公衆號EAWorld,違者必究。數據庫
分佈式事務解決的問題很明確,就是在服務分佈在不一樣進程、數據分佈在不一樣數據庫時,如何解決數據一致性問題。對於這個問題,業界的共識是不要啓用數據庫 XA 模式,由於分佈式狀況下,若是啓用了 XA 事務,必然會有數據庫鎖存在,實際上形成了兩個服務之間的耦合,與分佈式服務的初衷背離,還不如部署在一塊兒。在不使用 XA 的狀況下,常用業務補償和TCC(Try/Confirm/Cancel)模式的服務來解決:爲何有這樣兩種模式呢,他們有什麼區別,各自適合什麼樣的場景,這兩種模式是否帶來了代碼開發的複雜度?常常有人問我這樣的問題,這裏簡單說明一下:微信
用補償交易保證數據一致性架構
解決數據一致性問題,能夠經過業務補償的方式完成。實際上業務補償是一種業務提出的要求,在銀行咱們能夠把交易(服務)分爲帳務類和查詢類交易(在這裏服務和交易是等同的,我就再也不專門區分了),對於帳務類交易,能夠提供補償交易,一旦業務失敗能夠調用補償交易,經過沖正等方式進行,如何補償在業務上是有明肯定義的,不能隨意而爲。(不要擔憂這樣作開發起來複雜了,這是必須作的需求)。框架
當年不少業務在失敗的時候,是由人工發起補償交易的(我在阿里展覽館就要這樣的展品,在一個小本本上手工記錄的交易金額、流水號等,早期的支付寶就是這樣衝正的)。這樣作法效率低,咱們就但願可以經過技術手段,在業務失敗的時候自動發起補償交易,減小人工參與。爲此,咱們能夠開發一個自動補償的框架,記錄每一個處理過的業務交易流水,在處理某個交易失敗的時候,依次調用補償交易,流程以下:分佈式
TCC服務(交易)的使用場景微服務
銀行的帳務類交易除了補償類交易以外,還有一種 TCC 類型的服務,這類交易的 T 是 Try 的一塊兒,也就是開始時預留資源,在 Confirm 的時候改變最終資源,或者在 Cancel 的時候釋放預留資源。例如,在銀行帳目中,都有餘額和可用餘額兩個字段,在 T 的時候,首先改變可用餘額,業務上用可用餘額來進行判斷,而不是用實際餘額判斷,在 Confirm 的時候,修改實際餘額,在 Cancel 的時候,修改可用餘額。大數據
這樣作的好處是,在業務失敗的狀況下,實際餘額不會出現變化。我常常遇到的問題是:雲計算
有了補償服務爲何還要 TCC,有什麼好處,爲何不能直接修改帳戶餘額;設計
TCC 服務要用什麼樣的框架實現。3d
TCC 這種作法有什麼好處
之前面帳戶餘額和可用餘額的例子看,帳戶餘額的調整會涉及到不少方面,不只僅是一個字段數值的更新,根據會計原則,帳戶餘額的變化須要生成會計分錄、登記帳務流水、計算利率變化、計算稅率變化等等,除此以外,帳戶餘額的變化還會引發關聯帳戶的變化,牽一髮動全身。在業務失敗的時候,若是調用補償交易,就須要對上述操做作處理,業務處理太複雜,得不償失。所以,通常會設計一個可用餘額,首先改變可用餘額,業務成功時再調整帳戶實際餘額。根據這個示例,咱們也能夠清楚,在什麼場景下須要 TCC 服務了。其實,在金融交易中,就有專門的預付費交易,就能夠用來支持 TCC 模式。
(點擊圖片可放大)
TCC 服務要用什麼樣的框架實現?
從上述示例能夠看出,TCC和補償式交易同樣,都是爲了知足業務的要求,而這些交易剛好能夠用來爲數據一致性服務,TCC服務的 T、C、C實現,徹底是根據業務須要實現,不可能有一個統一的實現框架,例如帳戶餘額的作法和庫存餘額的作法,多是差距很大的,沒有必要抽象出來。互聯網上雖然有實現 TCC 服務的方式,可是也都是針對特定業務的,不具有通用型。
可是,爲何每每有人提出,框架要支持 TCC 呢,究其緣由是把 TCC 服務和數據一致性框架混爲一談了,前者是一個服務實現,後者是利用服務的特色保證數據完整性,減小人工操做。
數據一致性框架,除了利用 TCC/補償服務的框架以外,還有利用冪等服務特性實現的重試性框架,也就是利用交易的冪等特性,反覆進行重試,若是屢次重試仍是不成功,只有採用人工手段了。
總結一下:
補償類服務和 TCC 服務是處理重要信息變動的兩種模式,能夠經過這兩種模式,來支持數據一致性。這兩種方式都是特定業務的須要,而不是 XA事務、重試這樣,用一種技術手段實現數據一致性。對於簡單的業務來講,這兩種方式是沒有必要的,可是對於重要信息的變動,尤爲是分佈式系統從渠道、中臺、核心多環節完成信息變動時,這是必須的。
關於做者:焦烈焱,普元信息CTO,致力於技術創新和金融創新解決方案研究。專一於企業技術架構領域,對分佈式環境的企業計算、 企業信息架構的規劃與實踐有着豐厚經驗,帶領普元技術團隊相繼在雲計算、大數據及移動開發領域取得多項突破,並主持中國工商銀行、中國建設銀行等多家大型企業技術平臺的規劃與研發。
關於EAWorld:微服務,DevOps,數據治理,移動架構原創技術分享。長按二維碼關注!