關於TCC分佈式事務

今日,阿里電話面試,問了TCC,直接當場懵了,必須惡補分佈式相關知識,記錄一下。

在當前如火如荼的互聯網浪潮下,如何應對海量數據、高併發成爲大家面臨的普遍難題。廣大IT公司從以往的集中式網站架構,紛紛轉向分佈式的網站架構,隨之而來的就是進行數據庫拆分和應用拆分,如何在跨數據庫、跨應用保證數據操作和業務操作的一致性、原子性,又成爲需要解決的新的問題。從分佈式事務的需求來源來看:
1、跨數據庫

 

  • 數據庫拆分(水平、垂直)帶來的分佈式事務->保證跨庫操作的原子性
  • 基於單個JVM

2、跨應用

 

  • 應用拆分帶來的分佈式事務->保證跨應用業務操作的原子性
  • 跨JVM

跨應用的業務操作原子性要求,其實是比較常見的。比如在第三方支付場景中的組合支付,用戶在電商網站購物後,要同時使用餘額和紅包支付該筆訂單,而餘額系統和紅包系統分別是不同的應用系統,支付系統在調用這兩個系統進行支付時,就需要保證餘額扣減和紅包使用要麼同時成功,要麼同時失敗。

 

 

TCC事務的出現正是爲了解決應用拆分帶來的跨應用業務操作原子性的問題。當然,由於常規的XA事務(2PC,2 Phase Commit, 兩階段提交)性能上不盡如人意,也有通過TCC事務來解決數據庫拆分的使用場景(如賬務拆分),這個本文後續部分再詳述。

故從整個系統架構的角度來看,分佈式事務的不同方案是存在層次結構的:分佈式事務之說說TCC事務

 

TCC的機制

明眼一看就知道,TCC應該是三個英文單詞的首字母縮寫而來。沒錯,TCC分別對應Try、Confirm和Cancel三種操作,這三種操作的業務含義如下:

  • Try:預留業務資源
  • Confirm:確認執行業務操作
  • Cancel:取消執行業務操作

       稍稍對照下關係型數據庫事務的三種操作:DML、Commit和Rollback,會發現和TCC有異曲同工之妙。在一個跨應用的業務操作中,Try操作是先把多個應用中的業務資源預留和鎖定住,爲後續的確認打下基礎,類似的,DML操作要鎖定數據庫記錄行,持有數據庫資源;Confirm操作是在Try操作中涉及的所有應用均成功之後進行確認,使用預留的業務資源,和Commit類似;而Cancel則是當Try操作中涉及的所有應用沒有全部成功,需要將已成功的應用進行取消(即Rollback回滾)。其中Confirm和Cancel操作是一對反向業務操作。

分佈式事務之說說TCC事務

簡而言之,TCC是應用層的2PC(2 Phase Commit, 兩階段提交),如果你將應用看做資源管理器的話。       詳細來說,TCC每項操作需要做的事情如下:1、Try:嘗試執行業務。

  • 完成所有業務檢查(一致性)
  • 預留必須業務資源(準隔離性)

2、Confirm:確認執行業務。

  • 真正執行業務
  • 不做任何業務檢查
  • 只使用Try階段預留的業務資源

3、Cancel:取消執行業務

  • 釋放Try階段預留的業務資源

       用一張圖來說明TCC的機制:

分佈式事務之說說TCC事務

一個完整的TCC事務參與方包括三部分:

  • 主業務服務:主業務服務爲整個業務活動的發起方,如前面提到的組合支付場景,支付系統即是主業務服務。
  • 從業務服務:從業務服務負責提供TCC業務操作,是整個業務活動的操作方。從業務服務必須實現Try、Confirm和Cancel三個接口,供主業務服務調用。由於Confirm和Cancel操作可能被重複調用,故要求Confirm和Cancel兩個接口必須是冪等的。前面的組合支付場景中的餘額系統和紅包系統即爲從業務服務。
  • 業務活動管理器:業務活動管理器管理控制整個業務活動,包括記錄維護TCC全局事務的事務狀態和每個從業務服務的子事務狀態,並在業務活動提交時確認所有的TCC型操作的confirm操作,在業務活動取消時調用所有TCC型操作的cancel操作。

       可見整個TCC事務對於主業務服務來說是透明的,其中業務活動管理器和從業務服務各自幹了一部分工作。

 

 

TCC的優點和限制

 

 TCC事務的優點如下:

  • 解決了跨應用業務操作的原子性問題,在諸如組合支付、賬務拆分場景非常實用。
  • TCC實際上把數據庫層的二階段提交上提到了應用層來實現,對於數據庫來說是一階段提交,規避了數據庫層的2PC性能低下問題。

       TCC事務的缺點,主要就一個:

  • TCC的Try、Confirm和Cancel操作功能需業務提供,開發成本高。

       當然,對TCC事務的這個缺點是否是缺點,是一個見仁見智的事情。

 

 

一個案例理解

TCC說實話,TCC的理論有點讓人費解。故接下來將以賬務拆分爲例,對TCC事務的流程做一個描述,希望對理解TCC有所幫助。       賬務拆分的業務場景如下,分別位於三個不同分庫的帳戶A、B、C,A和B一起向C轉帳共80元:分佈式事務之說說TCC事務

1、Try:嘗試執行業務。

  • 完成所有業務檢查(一致性):檢查A、B、C的帳戶狀態是否正常,帳戶A的餘額是否不少於30元,帳戶B的餘額是否不少於50元。
  • 預留必須業務資源(準隔離性):帳戶A的凍結金額增加30元,帳戶B的凍結金額增加50元,這樣就保證不會出現其他併發進程扣減了這兩個帳戶的餘額而導致在後續的真正轉帳操作過程中,帳戶A和B的可用餘額不夠的情況。


2、Confirm:確認執行業務。

  • 真正執行業務:如果Try階段帳戶A、B、C狀態正常,且帳戶A、B餘額夠用,則執行帳戶A給賬戶C轉賬30元、帳戶B給賬戶C轉賬50元的轉帳操作。
  • 不做任何業務檢查:這時已經不需要做業務檢查,Try階段已經完成了業務檢查。
  • 只使用Try階段預留的業務資源:只需要使用Try階段帳戶A和帳戶B凍結的金額即可。


3、Cancel:取消執行業務

  • 釋放Try階段預留的業務資源:如果Try階段部分成功,比如帳戶A的餘額夠用,且凍結相應金額成功,帳戶B的餘額不夠而凍結失敗,則需要對帳戶A做Cancel操作,將帳戶A被凍結的金額解凍掉。


小結:到底要不要使用TCC到底要不要使用TCC事務,取決於以下幾點:

  • 是否真正有保證跨應用業務操作的原子性需求。
  • 研發上能否投入資源開發相對應的TCC接口。
  • 當然還有最後一點,能否搞定一個穩定的、高可用的、擴展性強的TCC事務管理器。

       一個問題,如果TCC事務在Try階段所有參與方(從業務服務)成功了,但是Confirm階段部分參與方(從業務服務)成功,如何處理?

 

TCC參考資料

《大規模SOA系統中的分佈式事務處理》:螞蟻金服CTO程立早年的一篇關於分佈式事務的PPT,裏面有關於大規模SOA系統中包括TCC在內的各種分佈式事務處理方案,是支付寶在分佈式事務實踐的經驗精華。

《Atomic Distributed Transactions: a RESTful Design》:ATOMIKOS公司的Guy Pardon和另一位作者一同寫的一篇關於TCC事務設計方案的論文,對TCC的實現細節描述較爲清楚。

--------------------- 本文來自 kobejayandy 的CSDN 博客 ,全文地址請點擊:https://blog.csdn.net/kobejayandy/article/details/54783212?utm_source=copy

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章