TCC是Try、Confirm、Cancel三個詞語的縮寫,要求每個分支事務執行三個操作:
預處理Try :做業務檢查和資源預留
確認Confirm :做業務確認
撤銷Cancel :實現回滾操作
TM首先會發起所有分支事務的try操作,任何壹個分支事務的try操作執行失敗,TM將會發起所有分支事務的Cancel操作,若try全部成功,TM將會發起所有分支事務的confirm操作,其中,若confirm、cancel執行失敗,TM會進行重試。
1)Try階段是做業務檢查(壹致性)及資源預留(隔離)。
2)Confirm階段是做確認提交,Try階段所有分支事務執行成功開始執行confirm。
通常情況下使用TCC則認為在Confirm階段不會出錯,只要try成功,confirm壹定成功。若confirm出錯,則進行重試或人工處理。
3)Cancel階段是在業務執行錯誤需要回滾的狀態下,執行其他未失敗的分支事務的取消,即預留資源的釋放。
通常情況下,TCC的Cancel階段也認為是壹定成功的,若出錯曾引入重試或人工處理。
以下幾個框架均支持TCC全局事務,目前阿裏seata擁有較大的用戶基數,github的star數也是遙遙領先,後面會逐步增加seata實戰源碼。
在Try階段,假設對服務A發送Try請求,由於網絡原因導致網絡超時,此時協調器收到網絡超時的響應,需要在第二步進行cancel操作。可是服務A在Try階段根本沒有執行成功,這樣就導致了數據不壹致。
解決問題的關鍵是如何在Try階段識別出服務A是否執行成功了,如果成功了就執行commit,如果失敗了,就執行空回滾。可以增加壹張分支事務記錄表,記錄分支事務和全局事務id,當請求超時後可以通過此表查看分支事務,執行Try則記錄,沒有則走空回滾。
主要出現在Try階段。在confirm或cancel前先進行查詢,通過增加壹張事務狀態表。
更加嚴謹需要增加分布式鎖。
由於超時等原因,cancel比try先執行,就是懸掛問題。
解決方案增加分支事務記錄表,先去查詢,如果cancel已經執行,則不再執行try。