saga-orchestration について
2フェーズコミットを使わずに分散トランザクションや長時間の業務プロセスを調整するSaga設計スキルです。補償処理、タイムアウト、監視の設計を支援します。
主な機能
- 01順序付きSagaステップとコマンドの定義
- 02オーケストレーションまたはコレオグラフィーの設計
- 03冪等な補償ロジックの設計
- 04ステップごとのタイムアウト設定
- 05状態指標と停滞Sagaの検出
活用シーン
- 01サービス間トランザクションの調整
- 02部分的な失敗からの復旧
- 03長時間の業務ワークフローの実行
- 04注文、承認、予約フローの設計
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ wshobson/ agents --skill saga-orchestrationインストール後、Claude Code で/saga-orchestrationを入力して読み込まれたか確認します。
同梱ファイルreferences/details.mdreferences/advanced-patterns.md
詳細
Saga オーケストレーション
2 フェーズコミットを使わずに、分散トランザクションと長時間実行されるビジネスプロセスを管理するためのパターンです。
入力と出力
提供していただくもの:
- サービスの境界と所有権 (どのサービスがどのステップを所有するか)
- トランザクションの要件 (どのステップをアトミックにする必要があり、どれを結果整合でよいか)
- 各ステップの障害モード (一時的か恒久的か、リトライポリシー)
- ステップごとの SLA 要件 (タイムアウト設定の根拠になります)
- 既存のイベント/メッセージング基盤 (Kafka、RabbitMQ、SQS など)
このスキルが生成するもの:
- 順序付けられたステップ、アクションコマンド、補償コマンドを含む Saga 定義
- 選択したパターンに応じたオーケストレーターまたはコレオグラフィの実装
- 各参加サービス向けの補償ロジック (冪等で、常に成功するもの)
- ステップごとのデッドラインを含むステップタイムアウト設定
- モニタリングの設定: ステートマシンのメトリクス、スタックした Saga の検出、DLQ リカバリ
このスキルを使うべきとき
- 分散ロックを使わずにマルチサービス間のトランザクションを調整する場合
- 部分的な失敗に対する補償トランザクションを実装する場合
- 長時間実行されるビジネスワークフロー (数分から数時間) を管理する場合
- アトミック性が求められる分散システムでの障害を処理する場合
- 注文フルフィルメント、承認、予約のプロセスを構築する場合
- 脆弱な 2 フェーズコミットを非同期の補償で置き換える場合
詳細セクション: 中核となる概念
references/details.md に移動しました。
詳細セクション: テンプレート
references/details.md に移動しました。
ベストプラクティス
やるべきこと
- すべてのステップを冪等にする — ブローカーの再接続時にコマンドが再生される可能性があります
- 補償を慎重に設計する — 補償は最も重要なコードパスです
- 相関 ID を使用する —
saga_idはすべてのイベントとログを通じて流れる必要があります - ステップごとのタイムアウトを実装する — 参加者からの応答を無期限に待ってはいけません
- 状態遷移をログに記録する — すべての変更時に
saga_id、step_name、old_state → new_stateを記録します - 補償パスを明示的にテストする — 統合テストで各ステップのインデックスに障害を注入します
やってはいけないこと
- 即時完了を前提にしてはいけない — Saga は非同期であり、数分かかることがあります
- 補償のテストを省略してはいけない — ロールバックパスは最も正しく実装するのが難しい部分です
- サービスを直接結合してはいけない — 非同期メッセージングを使用し、Saga ステップ内で同期呼び出しを行ってはいけません
- 部分的な失敗を無視してはいけない — 部分的に実行されたステップにも補償が必要です
- グローバルタイムアウトを使用してはいけない — 各ステップのレイテンシ特性は異なります
トラブルシューティング
Saga が COMPENSATING 状態でスタックする
Saga が補償に入ったものの、FAILED に到達しません。これは、補償ハンドラーが未処理の例外をスローし、SagaCompensationCompleted を発行しないままになっていることを意味します。補償コンシューマーにデッドレターキュー (DLQ) の処理を追加し、基盤となる操作がすでにロールバックされている場合でも、すべての補償アクションが結果イベントを発行するようにしてください。
async def handle_release_reservation(self, command: Dict):
try:
await self.release_reservation(command["original_result"]["reservation_id"])
except ReservationNotFoundError:
pass # Already released — treat as success
# Always publish completion, regardless of outcome
await self.event_publisher.publish("SagaCompensationCompleted", {
"saga_id": command["saga_id"],
"step_name": "reserve_inventory"
})
再起動時に Saga が重複実行される
オーケストレーターサービスが Saga の途中で再起動すると、イベントを再生し、すでに完了したステップを再実行する可能性があります。すべてのステップアクションを冪等キーで保護してください — 上記の テンプレート 3 を参照してください。
コレオグラフィ Saga でイベントが失われる
コレオグラフィベースの Saga では、ダウンストリームサービスが発行時にオフラインだった場合、イベントを取りこぼす可能性があります。耐久性のあるメッセージブローカー (レプリケーション付きの Kafka、永続化付きの RabbitMQ) を使用し、現在の Saga 状態を専用の saga_log テーブルに保存して、最後に確認できた正常なステップから再生できるようにしてください。
遅いが有効なステップが完了する前にタイムアウトが発生する
create_shipment のようなステップはピーク負荷時に最大 15 分かかることがありますが、グローバルタイムアウトが 5 分だと、誤った補償が発生します。ステップタイムアウトをステップタイプごとに設定可能にしてください — TimeoutSagaOrchestrator の実装と STEP_TIMEOUTS ディクショナリのパターンについては references/advanced-patterns.md を参照してください。
補償の順序が実行順序と一致しない
2つのステップがどちらも失敗が検出される前に完了した場合、補償は厳密に逆順で実行する必要があります。そうでなければデータは不整合な状態のままになります。_compensate() が current_step - 1 から 0 に向かってイテレーションしていることを確認し、各ステップのインデックスで意図的に失敗させる統合テストを追加して、ロールバック順序が正しいことを確認してください。
高度なパターン
references/ ディレクトリには、ほとんどの Saga には不要な本番グレードの実装が含まれています。
references/advanced-patterns.md— 完全なSagaOrchestrator抽象基底クラス、ステップごとのデッドラインを持つTimeoutSagaOrchestrator、銀行振込の補償トランザクションチェーンの詳細、Prometheus のインストルメンテーション、スタックした Saga の PromQL アラート、DLQ リカバリワーカー。
関連スキル
cqrs-implementation— 各ステップの完了後にリードモデルを更新するため、Saga を CQRS と組み合わせるevent-store-design— 完全な監査証跡とリプレイ機能のために Saga イベントをイベントストアに保存するworkflow-orchestration-patterns— Saga の概念を基盤とする高レベルのワークフローエンジン(Temporal、Conductor)