Transactional Sagas#
Saga 的概念源於限制早期分散式架構中資料庫鎖的範圍,最早可追溯至 1987 年 ACM 會議的論文。Chris Richardson 將微服務的 saga pattern 描述為:一系列的 local transaction,每個更新發布一個事件,觸發序列中的下一個更新;若任何更新失敗,saga 會發出一系列 compensating update 來復原先前的變更。
分散式交易缺乏原子性,真正有趣的是錯誤發生時的處理。本章深入探討八種 transactional saga 模式及其取捨。

Figure 12.1: Legend for ISO architecture interaction diagrams
Transactional Saga Patterns#
三個交互維度(communication、consistency、coordination)的組合產生八種 saga 模式:
| Pattern 名稱 | Communication | Consistency | Coordination |
|---|---|---|---|
| Epic Saga(sao) | Synchronous | Atomic | Orchestrated |
| Phone Tag Saga(sac) | Synchronous | Atomic | Choreographed |
| Fairy Tale Saga(seo) | Synchronous | Eventual | Orchestrated |
| Time Travel Saga(sec) | Synchronous | Eventual | Choreographed |
| Fantasy Fiction Saga(aao) | Asynchronous | Atomic | Orchestrated |
| Horror Story(aac) | Asynchronous | Atomic | Choreographed |
| Parallel Saga(aeo) | Asynchronous | Eventual | Orchestrated |
| Anthology Saga(aec) | Asynchronous | Eventual | Choreographed |
上標字母代表三個維度的值(依字母順序:communication, consistency, coordination),例如 Epic Saga(sao) 代表 synchronous, atomic, orchestrated。
Epic Saga(sao) Pattern#
最「傳統」的 saga 模式,也稱為 Orchestrated Saga,模擬單體系統的行為。
- 使用 synchronous 通訊、atomic 一致性、orchestrated 協調
- Orchestrator 協調包含多個服務更新的工作流程,要求全部成功或全部失敗
- 使用 compensating update(補償更新) 來處理錯誤:反轉資料寫入操作(如復原更新、重新插入已刪除的列等)

Figure 12.2: The Epic Saga(sao) pattern's dynamic coupling

Figure 12.3: The isomorphic communication illustration of the Epic Saga(sao) pattern

Figure 12.4: A successful orchestrated transactional Epic Saga using a compensating update

Figure 12.5: When an error occurs, a mediator must send compensating requests
特性評估:
| 項目 | 評分 |
|---|---|
| Coupling | Very high |
| Complexity | Low |
| Responsiveness/availability | Low |
| Scale/elasticity | Very low |
雖然 compensating transaction 看似乾淨的解決方案,但認識到模式存在不等於解決了問題。分散式交易充滿困難,應盡可能避免。
Phone Tag Saga(sac) Pattern#
將 Epic Saga 的 coordination 從 orchestrated 改為 choreographed。
- 初始服務成為協調點(front controller),完成工作後傳給下一個服務
- 每個服務必須內建錯誤處理和 compensating request 的邏輯
- 適合簡單工作流程,需要比 Epic Saga 更好的擴展性

Figure 12.6: The Phone Tag pattern utilizes loosely coupled communication
特性評估:
| 項目 | 評分 |
|---|---|
| Coupling | High |
| Complexity | High |
| Responsiveness/availability | Low |
| Scale/elasticity | Low |
Fairy Tale Saga(seo) Pattern#
放寬了 atomic 要求,改用 eventual consistency,是許多微服務架構中常見且受歡迎的模式。
- 使用 synchronous 通訊、eventual 一致性、orchestrated 協調
- Orchestrator 負責協調請求、回應和錯誤處理,但不負責管理交易
- 每個領域服務管理自己的交易行為,整體工作流程依賴最終一致性
- 最大的吸引力在於沒有全域交易的需求

Figure 12.8: The Fairy Tale Saga(seo) illustrates eventual consistency

Figure 12.9: Isomorphic illustration of a Fairy Tale interaction
特性評估:
| 項目 | 評分 |
|---|---|
| Coupling | High |
| Complexity | Very low |
| Responsiveness/availability | Medium |
| Scale/elasticity | High |
Fairy Tale Saga 結合了最方便的選項(orchestrated、synchronous)和最寬鬆的限制(eventual consistency),是架構師的熱門選擇。
Time Travel Saga(sec) Pattern#
使用 synchronous 通訊和 eventual consistency,但採用 choreographed 工作流程。
- 避免中央 mediator,工作流程責任完全在參與的領域服務上
- 可實作 Chain of Responsibility 設計模式或 Pipes and Filters 架構風格
- 每個服務「擁有」自己的交易上下文,狀態會隨時間逐漸一致
- 非常適合高吞吐量的 fire and forget 工作流程(如電子資料擷取、批次交易)

Figure 12.10: The Time Travel Saga(sec) pattern uses two of three decoupling techniques

Figure 12.11: Complex workflows become difficult to manage without orchestration
特性評估:
| 項目 | 評分 |
|---|---|
| Coupling | Medium |
| Complexity | Low |
| Responsiveness/availability | Medium |
| Scale/elasticity | High |
Fantasy Fiction Saga(aao) Pattern#
使用 asynchronous 通訊、atomic 一致性、orchestrated 協調。
- 看似只是將 Epic Saga 的通訊改為非同步以提升效能,但實際上增加了大量複雜度
- 非同步通訊移除了序列假設,增加了 deadlock、race condition 等平行系統問題
- 當多個交易工作流程同時進行且有依賴關係時,mediator 必須追蹤所有待處理交易的狀態

Figure 12.12: Asynchronous communication makes transactionality difficult

Figure 12.13: The Fantasy Fiction Saga(aao) pattern is far-fetched

Figure 12.14: The most difficult combination: achieving transactionality while asynchronous
特性評估:
| 項目 | 評分 |
|---|---|
| Coupling | High |
| Complexity | High |
| Responsiveness/availability | Low |
| Scale/elasticity | Low |
此模式比它應有的受歡迎程度更高,通常是架構師誤以為將 Epic Saga 改為非同步即可提升效能的結果。更好的替代方案是 Parallel Saga(aeo)。
Horror Story(aac) Pattern#
最糟糕的組合之一:asynchronous 通訊 + atomic 一致性 + choreographed 協調。
- 結合了最嚴格的耦合需求(atomic)與最鬆散的耦合風格(asynchronous + choreography)
- 沒有 mediator 來管理跨多個服務的交易一致性
- 每個領域服務必須追蹤多個待處理交易的 undo 資訊,且可能順序錯亂

Figure 12.15: This pattern requires a lot of interservice communication
特性評估:
| 項目 | 評分 |
|---|---|
| Coupling | Medium |
| Complexity | Very high |
| Responsiveness/availability | Low |
| Scale/elasticity | Medium |
Horror Story 通常是架構師從 Epic Saga 出發,發現效能慢後嘗試加入 asynchronous 和 choreography 的結果,但忽略了各維度之間的糾纏。
Parallel Saga(aeo) Pattern#
以 Epic Saga 為基礎,放寬兩個限制:改用 asynchronous 通訊和 eventual 一致性。
- 使用 mediator 協調複雜工作流程,但以非同步通訊提升回應性和平行執行
- 每個服務維護自己的交易邊界,consistency 由各服務負責
- 錯誤發生時,mediator 可發送非同步訊息給相關服務進行補償

Figure 12.16: Parallel Saga(aeo) offers performance improvements over traditional sagas

Figure 12.17: Each service owns its own transactionality; the mediator coordinates
特性評估:
| 項目 | 評分 |
|---|---|
| Coupling | Low |
| Complexity | Low |
| Responsiveness/availability | High |
| Scale/elasticity | High |
Parallel Saga 對許多場景提供了有吸引力的取捨組合,特別適合需要高擴展性的複雜工作流程。
Anthology Saga(aec) Pattern#
與 Epic Saga 完全相反:使用 asynchronous 通訊、eventual 一致性、choreographed 協調,是耦合最低的模式。
- 使用 message queue 在服務間傳遞非同步訊息,沒有 orchestrator
- 每個服務維護自己的交易完整性,服務必須包含更多工作流程上下文
- 沒有瓶頸或耦合節點,可實現高回應性和擴展性
- 不適合複雜或關鍵的工作流程,因為協調極為困難
- 可使用 stamp coupling 傳遞工作流程狀態

Figure 12.18: The Anthology Saga(aec) pattern offers the opposite extremes of the Epic Saga

Figure 12.19: Lack of orchestration, eventual consistency, and asynchronicity make this pattern difficult
特性評估:
| 項目 | 評分 |
|---|---|
| Coupling | Very low |
| Complexity | High |
| Responsiveness/availability | High |
| Scale/elasticity | Very high |
State Management and Eventual Consistency#
狀態管理和最終一致性利用 finite state machine(有限狀態機) 來追蹤 transactional saga 的當前狀態,並透過重試或人工修復最終修正錯誤。
以 Fairy Tale Saga(seo) 實作的 ticket 完成流程為例:
- 當 Survey Service 不可用時,saga 狀態改為 NO_SURVEY,仍回傳成功給用戶
- Ticket Orchestrator Service 在背景非同步處理錯誤(重試或送交管理員手動處理)
- 終端使用者不受錯誤影響,回應性更好
Saga State Machines#
State machine 描述分散式架構中所有可能的路徑,包含起始狀態、轉換狀態和對應的動作。
以 Sysops Squad 新問題單為例,狀態流程為:

Figure 12.21: State diagram for creating a new problem ticket
START → CREATED → ASSIGNED → ACCEPTED → COMPLETED → CLOSED
額外的錯誤路徑:
- ACCEPTED → REASSIGN(專家無法修復)→ ASSIGNED
- COMPLETED → NO_SURVEY(問卷服務不可用)→ CLOSED
將所有狀態轉換和對應動作列成表格,開發人員可據此實作 orchestrator 或各服務中的狀態轉換觸發器和錯誤條件。
State Management vs. Compensating Updates 的取捨#
| 優勢 | 劣勢 |
|---|---|
| 良好的回應性 | 錯誤時資料可能暫時不同步 |
| 錯誤對終端使用者影響較小 | 最終一致性可能需要一些時間 |
Techniques for Managing Sagas#
分散式交易無法簡單地「引入」系統,必須經過設計、編碼和維護。
一個實用技術是使用 annotations(Java)或 custom attributes(C#)來標記服務參與的 saga:
- 定義
@Sagaannotation,包含Transactionenum(如NEW_TICKET、CANCEL_TICKET等) - 在各服務的 entry point 類別上標註所參與的 saga
- 可撰寫 code-walking tool 自動掃描 codebase,查詢特定 saga 涉及哪些服務
這種 annotation 方式提供了以程式化方式捕獲、記錄系統中所有 transactional saga 的能力,幫助開發人員了解變更的影響範圍。
Sysops Squad Saga: Atomic Transactions and Compensating Updates#
團隊討論 Epic Saga 模式下 ticket 完成工作流程的問題:

Figure 12.22: The epic saga requires the ticket status to be updated and survey to be sent
Epic Saga 的三大挑戰#
1. 缺乏交易隔離(No Transaction Isolation)
- 在分散式交易中沒有隔離機制,其他服務可能在交易完成前就使用了已更新的資料
- 例如:Ticket Service 非同步發送資料給 Analytics Service(步驟 4-5),但 compensating update(步驟 7)執行時,Analytics 已處理了該資料
- 這種 side effect 極難修復,因為下游可能有更多連鎖反應

Figure 12.23: Epic Saga(sao) requires compensation, but side effects can occur
2. Compensating Update 可能失敗
- 假設 compensating update 一定會成功是危險的
- 當 compensation 本身失敗時,系統處於不一致狀態,且不確定該回傳什麼給終端使用者

Figure 12.24: Compensating updates within an Epic Saga can fail
3. 回應性差
- Atomic 分散式交易必須等待所有 corrective action 完成後才能回應使用者
- 使用 eventual consistency(如 Fairy Tale Saga 或 Parallel Saga)可改善回應性
Compensating Updates 的取捨#
| 優勢 | 劣勢 |
|---|---|
| 所有資料恢復至先前狀態 | 沒有交易隔離 |
| 允許重試和重啟 | Compensation 時可能發生 side effect |
| Compensation 本身可能失敗 | |
| 終端使用者回應性差 |
關鍵洞察#
- 現實世界中大部分事情並非交易性的(如 Gregor Hohpe 的著名文章「Starbucks Does Not Use Two-Phase Commit」)
- 交易協調是架構中最困難的部分之一,範圍越廣越困難
- 更實際的方案是使用 Fairy Tale Saga 或 Parallel Saga,依賴非同步的 eventual consistency 和狀態管理,而非 atomic 分散式交易和 compensating update