分佈式事務系列--Saga

簡介

        Saga是30年前一篇數據庫倫理提到的一個概念。其核心思想是將長事務拆分爲多個本地短事務,由Saga事務協調器協調,如果正常結束那就正常完成,如果某個步驟失敗,則根據相反順序一次調用補償操作。 Saga的組成:

        每個Saga由一系列sub-transaction Ti 組成 每個Ti 都有對應的補償動作Ci,補償動作用於撤銷Ti造成的結果,這裏的每個T,都是一個本地事務。 可以看到,和TCC相比,Saga沒有“預留 try”動作,它的Ti就是直接提交到庫。

Saga的執行順序有兩種:

  • T1, T2, T3, ..., Tn
  • T1, T2, ..., Tj, Cj,..., C2, C1,其中0 < j < n

Saga定義了兩種恢復策略:

  • 向後恢復,即上面提到的第二種執行順序,其中j是發生錯誤的sub-transaction,這種做法的效果是撤銷掉之前所有成功的sub-transation,使得整個Saga的執行結果撤銷。
  • 向前恢復,適用於必須要成功的場景,執行順序是類似於這樣的:T1, T2, ..., Tj(失敗), Tj(重試),..., Tn,其中j是發生錯誤的sub-transaction。該情況下不需要Ci。

        這裏要注意的是,在saga模式中不能保證隔離性,因爲沒有鎖住資源,其他事務依然可以覆蓋或者影響當前事務。

還是拿100元買一瓶水的例子來說,這裏定義

T1=扣100元,T2=給用戶加一瓶水,T3=減庫存一瓶水

C1=加100元,C2=給用戶減一瓶水,C3=給庫存加一瓶水

        我們一次進行T1,T2,T3如果發生問題,就執行發生問題的C操作的反向。 上面說到的隔離性的問題會出現在,如果執行到T3這個時候需要執行回滾,但是這個用戶已經把水喝了(另外一個事務),回滾的時候就會發現,無法給用戶減一瓶水了。這就是事務之間沒有隔離性的問題。

        可以看見saga模式沒有隔離性的影響還是較大,可以參照華爲的解決方案:從業務層面入手加入一 Session 以及鎖的機制來保證能夠串行化操作資源。也可以在業務層面通過預先凍結資金的方式隔離這部分資源, 最後在業務操作的過程中可以通過及時讀取當前狀態的方式獲取到最新的更新。

中間件實例

具體實例:參考華爲的servicecomb

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