Saga パターン (オーケストレーション)
分散トランザクションを複数のローカルトランザクションに分割し、中央のオーケストレーターが制御するパターン
Saga オーケストレーションとは
Saga パターンのオーケストレーション方式は、中央のオーケストレーター (指揮者) が各サービスのローカルトランザクションを順番に呼び出し、失敗時には補償トランザクションを逆順に実行する方式である。AWS Step Functions が代表的なオーケストレーターだ。
Saga は ACID の分離性 (Isolation) を保証しない。処理の途中では「在庫は引き当て済みだが決済は未完了」という中間状態が他の処理から見えてしまう。そのため、引き当て済みを表すステータスを持たせて確定前の在庫を売らないようにするなど、業務データ側で意味的なロックを設計する必要がある。
処理の流れ
オーケストレーション方式では、Step Functions などの中央コーディネーターが各サービスの呼び出し順序を制御する。途中で失敗した場合は、完了済みのステップに対して補償トランザクション (逆操作) を実行してロールバックする。
1. 注文サービス: 注文作成 → 成功
2. 在庫サービス: 在庫引き当て → 成功
3. 決済サービス: 支払い処理 → 失敗!
4. 補償: 在庫サービス: 在庫を戻す
5. 補償: 注文サービス: 注文をキャンセル
コレオグラフィとの比較
選択の分かれ目は、フローの手順を 1 か所に集めて追跡しやすさを取るか、サービス間の依存を減らして各サービスの独立性を取るかである。
| 観点 | オーケストレーション | コレオグラフィ |
|---|---|---|
| 制御 | 中央 (Step Functions) | 分散 (各サービスが自律) |
| 可視性 | 高い (フロー全体が可視化) | 低い (フローが見えにくい) |
| 結合度 | 中程度 (オーケストレーターに依存) | 低い (イベントのみ) |
| 複雑なフロー | 得意 (条件分岐、並列実行) | 苦手 |
| 適するケース | 条件分岐や並列を含む多段のフロー | 手順が固定した短いフロー |
Step Functions の利点
- フロー全体を Amazon States Language (JSON) で宣言し、コンソールのワークフロー図で構造を確認できる。CloudFormation や SAM のテンプレートに書く場合は YAML でも表現できる
- 各ステップのリトライ、タイムアウト、エラーハンドリング (
Retry/Catch) が宣言的に設定できる - Standard ワークフローは実行履歴が Step Functions 側に記録され、直近 90 日分をコンソールから追える。Express ワークフローは実行履歴を保持しないため、後から追うには CloudWatch Logs へのログ出力設定が必要になる
- 並列実行 (
Parallelステート) や条件分岐 (Choiceステート) をサポート
補償トランザクションの設計
補償トランザクションはべき等に実装する。同じ補償が複数回実行されても安全であること。
// ❌ 非べき等: 2 回実行すると在庫が 2 回戻る
async function releaseInventory(reservationId: string) {
const r = await db.reservation.findUnique({ where: { id: reservationId } });
await db.inventory.increment(r.productId, r.quantity);
}
// ✅ べき等: 引き当て済みの予約を解放できたときだけ在庫を戻す
async function releaseInventory(reservationId: string) {
const released = await db.reservation.updateMany({
where: { id: reservationId, status: 'reserved' },
data: { status: 'released' },
});
if (released.count === 0) return; // 既に解放済み
const r = await db.reservation.findUnique({ where: { id: reservationId } });
await db.inventory.increment(r.productId, r.quantity);
}
実務で最初に決めること
オーケストレーション型を選ぶときに効いてくるのは、フロー全体が図で見えることよりも「打ち消せない工程をどこに置くか」である。在庫の引き当てや仮売上は補償で戻せるが、送信済みの通知や外部倉庫へ渡した出荷指示は戻せない。戻せない工程を手順の後ろへ寄せ、それより前を補償可能な範囲として設計しておけば、失敗した時に取れる手が残る。
もう 1 つは、補償側のコードを本流と同じ重みでテストすることである。補償は正常系では一度も通らないため、書いたまま実行されずに本番へ出やすい。途中の工程を意図的に失敗させる試験を用意しておかないと、いざ動いた時に補償自体が失敗し、中途半端な状態がそのまま残る。
この記事は役に立ちましたか?
関連用語
Saga コレオグラフィ
各サービスがイベントを発行 / 購読し、中央のオーケストレーターなしで分散トランザクションを実現する方式
Step Functions
AWS のサーバーレスワークフローサービスで、Lambda 関数を視覚的に組み合わせてオーケストレーションする
イベント駆動アーキテクチャ
イベントの発行と購読を中心にシステムを構成し、サービス間の疎結合と非同期処理を実現するアーキテクチャスタイル
Aurora
AWS のクラウドネイティブ RDB で、MySQL/PostgreSQL 互換で高可用性と高パフォーマンスを実現する
X-Ray
AWS の分散トレーシングサービスで、リクエストの経路とレイテンシを可視化する
ステートレス
プロセスが内部に状態を持たず、リクエストごとに独立して処理する設計原則
関連する記事
技術書の読む順番戦略 - 複数冊を組み合わせて理解を加速させる
技術書を 1 冊ずつ読むのではなく、複数冊を戦略的に組み合わせることで、1 冊では届かない理解の深さと広さに達する方法を解説します。
深夜 3 時のデプロイ前に読み返したい 1 ページ
本番デプロイの直前、最終確認のチェックリストとして技術書の特定のページが役立つことがあります。緊張の場面で頼りになる「お守りの 1 ページ」の見つけ方と活用法。
インフラ / クラウド本ガイド - AWS や Docker を本で学ぶ
クラウドインフラ、コンテナ、IaC を学べる技術書の選び方と学習順序を紹介。インフラ本の賞味期限問題と公式ドキュメントとの使い分けも解説します。