分佈式事務(4)---最終一致性方案之TCC 分佈式事務(1)-理論基礎 分佈式事務(2)---強一致性分佈式事務解決方案 分佈式事務(3)---強一致性分佈式事務Atomikos實戰

分佈式事務(1)-理論基礎

分佈式事務(2)---強一致性分佈式事務解決方案

分佈式事務(3)---強一致性分佈式事務Atomikos實戰

強一致性分佈式事務解決方案要求參與事務的各個節點的數據時刻保持一致,在高併發場景下,系統的性能可能收到影響。而最終一致性方案並不要求數據時刻一致,允許其存在中間狀態,只要一段時間後數據能夠最終一致即可。

所以基於BASE理論,提出了最終一致性解決方案,典型的有:TCC解決方案,可靠消息最終一致性方案,最大努力通知型解決方案。

其優點是:

1.性能比較高,不會因爲長時間持有事務佔用資源。

2.具備可用性。

3.適合高併發場景。

缺點是,因爲數據的短暫不一致,所以會出現某一時刻數據的不一致。

對於一致性特別高的場景不適用。

我們實現最終一致性方案時,需要注意幾個操作:

可查詢操作:業務方需要提供可查詢接口,來查詢數據信息和狀態,供其他服務知道數據狀態。

冪等操作:同樣的參數執行同一個方法,返回的結果都一樣。在分佈式環境,難免會出現數據的不一致,很多時候爲了保證數據的一致,我們都會進行重試。如果不保證冪等,即使重試成功了,也無法保證數據的一致性。我們可以通過業務本身實現實現冪等,比如數據庫的唯一索引來約束;也可以緩存(記錄)請求和操作結果,當檢測到一樣的請求時,返回之前的結果。

補償操作:某些數據存在不正常的狀態,需要通過額外的方式使數據達到最終一致性的操作。

 

TCC

TCC解決方案主要包括三個階段:try---嘗試業務執行,confirm---確定業務執行,cancel---取消業務執行

try階段完成所有業務的一致性檢查,預留必要的業務資源。

confirm階段,真正執行業務,因爲try已經執行了資源預留,所以此階段不會再檢查數據,此階段的操作需要滿足冪等。

cancel階段,釋放try預留的業務資源,此階段也需要滿足冪等。

TCC主要用於跨服務調用下分佈式事務問題,適用於具有強隔離性,又嚴格要求一致性的業務場景。

舉個栗子

還是用下單扣庫存爲例

try階段:創建訂單,並將訂單狀態設置爲待提交,調用庫存服務預扣減庫存。庫存表中庫存字段減去訂單中的數量,同事在預扣減字段中增加訂單中庫存數量。以此來預留資源

confirm階段:如果try全部成功,則進入confirm階段。此階段將訂單狀態修改爲已提交,庫存服務則將預扣減庫存字段的數量減去訂單中的數量,實現真正的減庫存。

通常TCC方案我們都認爲confirm階段是不會出錯的。就是說只要try成功了,那麼confirm就一定會成功。如果confirm出錯了,那麼就需要引入補償機制或者人工處理。

cancel階段:try階段失敗或者出現異常,至此那個cancel,訂單狀態修改爲已取消,庫存服務將表中庫存字段增加訂單中的數量,預扣減字段減去訂單中的數量,以此實現事務回滾。同樣TCC中我們認爲cancel階段一定會執行成功,如果失敗也需要引入重試或者人工處理。

TCC方案中鎖定資源的粒度小,有利於提高系統性能;confirm和cancel階段的冪等保證分佈式事務執行完成後數據的一致性。由主業務放發起事務,無論是主業務還是分支業務都能集羣部署,解決了XA規範的單點故障問題。但是它的代碼需要耦合到業務中,參與分佈式事務的每個業務方法都需要try,confirm,cancel階段,增加開發成本。

 

TCC中需要注意的問題

1.空回滾

當一個分支事務所在的服務發生宕機或者網絡異常導致調用失敗,並未執行try方法,當恢復後事務執行回滾操作就會調用此分支事務的cancel方法,如果cancel方法不能處理此種情況就會出現空回滾。

是否出現空回滾,我們需要需要判斷是否執行了try方法,如果執行了就沒有空回滾。解決方法就是當主業務發起事務時,生成一個全局事務記錄,並生成一個全局唯一ID,貫穿整個事務,再創建一張分支事務記錄表,用於記錄分支事務,try執行時將全局事務ID和分支事務ID存入分支事務表中,表示執行了try階段,當cancel執行時,先判斷表中是否有該全局事務ID的數據,如果有則回滾,否則不做任何操作。比如seata的AT模式中就有分支事務表。

2.冪等問題

由於服務宕機或者網絡問題,方法的調用可能出現超時,爲了保證事務正常執行我們往往會加入重試的機制,因此就需要保證confirm和cancel階段操作的冪等性。

我們可以在分支事務記錄表中增加事務執行狀態,每次執行confirm和cancel方法時都查詢該事務的執行狀態,以此判斷事務的冪等性。

3.懸掛問題

TCC中,在調用try之前會先註冊分支事務,註冊分支事務之後,調用出現超時,此時try請求還未到達對應的服務,因爲調用超時了,所以會執行cancel調用,此時cancel已經執行完了,然而這個時候try請求到達了,這個時候執行了try之後就沒有後續的操作了,就會導致資源掛起,無法釋放。

執行try方法時我們可以判斷confirm或者cancel方法是否執行,如果執行了那麼就不執行try階段。同樣藉助分支事務表中事務的執行狀態。如果已經執行了confirm或者cancel那麼try就執行。

 

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