參考資料


  • ACID 交易的隔離性確保同時執行多個交易的結果,跟以某種串行順序執行它們的結果相同
  • 隔離性讓撰寫同時執行的商業邏輯變得容易許多
  • 使用 saga 的挑戰在於它們缺乏 ACID 交易的隔離性。
  • 問題
    • 其他 saga 可以在 saga 執行時變更它存取的資料
    • 其他 saga 可以在 saga 完成更新前讀取它的資料,因此可能讀到不一致的資料
  • saga 是 ACD 的:
    • 原子性 — saga 的實作確保所有交易都被執行,或所有變更都被復原。
    • 一致性 — 服務內部的參照完整性由本地資料庫處理。跨服務的參照完整性由服務自行處理。
    • 持久性 — 由本地資料庫處理。
  • 處理缺乏隔離性的策略:反制措施

異常狀況概觀
  • 遺失更新:更新一筆資料後,另一個 Saga 馬上覆寫同一筆資料
  • 髒讀:讀取一筆資料時,另一個 Saga 正在更新該資料但尚未完成
  • 模糊/不可重複讀取:Saga 的不同步驟讀取同一筆資料得到不同結果,因為其他 saga 做了更新

處理缺乏隔離性的反制措施
  • Semantic lock:應用層級的鎖
  • Commutative updates:設計可以任意順序執行的更新操作
  • Pessimistic view:重新排列 saga 步驟以最小化因髒讀造成的商業風險
  • Reread value:覆寫資料前重新讀取以驗證資料沒有被變更
  • Version file:記錄對記錄的更新,以便能重新排序。例如記錄到達的操作,然後以正確的順序執行
  • By value:用請求的商業風險來動態選擇並行機制。例如轉帳用分散式交易。簡單的狀態更新用 Saga。

SAGA 的結構

一個 saga 由三種類型的交易組成(一個完整的流程可能包含每種交易):
  • 可補償交易:有可能被回滾。例如刪除一個已建立的 Order
  • 關鍵交易:saga 中的決定性時刻。例如在繼續前進行驗證,驗證後決定要繼續還是停止。
  • 可重試交易:在關鍵交易之後,保證會成功。例如失敗時可以重試。