CTS-KB

開発手法ガイド:CES アプローチ編 — AI に長期トランザクションを任せる設計

⏱ 約 7 分で読めます
#開発手法#CES#CQRS#イベントソーシング#Saga#AI駆動開発

🤖 AI 駆動開発で CES が必要な理由

「注文 → 在庫引当 → 決済 → 配送手配」のように、 複数サービス・複数集約にまたがる長期トランザクション は、AI に任せると失敗する典型領域。AI は目の前の処理は書けても、 「どこで失敗したら、どう巻き戻すか」 の全体像を自力で組み立てにくい。

CES アプローチ(Command-Event-Saga)は、 CQRS + イベントソーシング + Saga を組み合わせ、長期トランザクションを明示的にモデリングする設計スタイル 。AI 駆動開発での効用は 3 つ。

AI 駆動開発での効用CES がもたらす状態
成功/失敗シナリオを AI に明示できるSaga の状態遷移が図として書ける
部分失敗を AI が安全に扱える補償トランザクションが業務イベントとして定義済み
トラブル時の調査を AI に任せられるイベント列+ Saga 状態で全経路が追跡可能

本記事は開発手法ガイド:概要のシリーズ 9 本目。CES の本質、Saga の設計、AI 駆動開発での適用を整理します。

📜 なぜ CES が必要か

2PC の限界

サービス境界(あるいは集約境界)を跨ぐ業務では、 2 フェーズコミット(2PC) は現実的でない。可用性が落ち、どこか 1 サービスが応答しないだけで全体がブロックされる。

マイクロサービス・外部 API 連携が前提の現代では、 結果整合性 + 補償 の仕組みが必要。それが Saga。

CES の構成要素

CES は 3 要素 を組み合わせる。

要素役割代表例
Command「◯◯せよ」という意図。受け付けて妥当性を検証PlaceOrderCommand
Event「◯◯が起きた」という事実。追記のみで不変OrderPlacedEvent
Saga複数 Event を協調させる長期プロセス。失敗時の補償を持つ注文 → 在庫 → 決済 → 配送の連鎖

🎭 Saga の 2 つのスタイル

Choreography(振付)

各サービスがイベントを購読して 自律的に次の動作を決める 。中央制御なし。

Sales Service        Inventory Service    Payment Service
  OrderPlaced ──────→ StockReserved ────→  PaymentCharged
  を発行              を発行             を発行
向いている場面向かない場面
関係サービスが少ない5 以上のサービスが絡む
疎結合を最優先フロー全体を俯瞰したい
各サービスが自律的失敗時の巻き戻し順序が複雑

Orchestration(指揮)

中央の Saga マネージャが 順序・リトライ・補償を制御 。フローが明示的。

Saga Orchestrator
  ├─ Step 1: Inventory.Reserve
  ├─ Step 2: Payment.Charge
  ├─ Step 3: Shipping.Schedule
  └─ 失敗時: 逆順に補償を発行
向いている場面向かない場面
フローが複雑・補償が多いサービス間を疎結合に保ちたい
進捗監視が必要小さい Saga の乱立
長時間実行(数分〜数時間)1 リクエスト内で完結

AI 駆動開発での選択基準

  • 3 サービス以内 + シンプル → Choreography
  • 4 サービス以上 or 補償が複雑 or 監視が必要 → Orchestration

AI に Saga を設計させるときは、この判断を先に人間がする。 「どちらのスタイルで作るか」を決めてから AI に指示する。

🔁 補償トランザクションが核心

Saga の核心は 失敗時の巻き戻しを業務イベントで表現する こと。DB のロールバックではなく、「在庫引当キャンセル」「決済返金」「注文取消」といった業務上のアクションを補償として発行する。

順方向イベント補償イベント
在庫引当在庫引当キャンセル
決済承認決済返金
注文確定注文取消
配送予約配送予約キャンセル
メール送信お詫びメール送信(物理的に取り消せない)

「取り消せないアクション」への対応

メール送信・物流連携など、 物理的に取り消せない アクションは、補償ではなく 後続の謝罪・通知フロー で対処する設計が現実解。

AI に指示するとき、 「このアクションは取り消せない。後続フローで対応する」 と明示しておくと、AI が無理にロールバックを書こうとしない。

🎯 AI 駆動開発での CES 実装

ステップ 1: Saga の状態遷移を先に書く

AI に実装を依頼する前に、 状態遷移図 を用意する。

[Started]
  ↓ OrderPlaced
[OrderAccepted]
  ↓ InventoryReserved
[StockReady]
  ↓ PaymentCharged
[Paid]
  ↓ ShippingScheduled
[Completed]

失敗時:
[Paid] → 配送失敗 → [Refunding] → [Cancelled]
[StockReady] → 決済失敗 → [ReleasingStock] → [Cancelled]

この図を CLAUDE.md や設計ドキュメントに書いておくと、AI への指示が一気に明確になる。

ステップ 2: 各ステップを個別に実装してもらう

指示例:
  OrderSaga の Step 2「InventoryReserved イベントを受けて
  Payment.Charge Command を発行する」ハンドラを実装してください。
  - Orchestration スタイル(中央 Saga マネージャ)
  - 失敗時は InventoryReleased 補償イベントを発行
  - Idempotency を保証(同じ ID で再実行しても結果が同じ)

ステップごとに実装すれば、AI が全体を一発で書こうとして破綻するのを防げる。

ステップ 3: 補償経路を別指示で実装する

順方向と補償は分けて指示 するのが鉄則。AI が順方向だけ書いて「補償は後で」となると、運用時に詰まる。

レビュー観点

  • Saga の状態遷移がドキュメントと一致しているか
  • 補償イベントが順方向と対応しているか
  • Idempotency(冪等性)を保証しているか
  • タイムアウトが設定されているか(無限待機していないか)
  • 部分失敗(ネットワーク切断、タイムアウト)に対して挙動が定義されているか
  • 「取り消せないアクション」が補償で無理に取り消されていないか

🧟 ゾンビ Saga と向き合う

Saga の運用で必ず出会うのが ゾンビ Saga 。

症状原因
中間状態のまま停止外部サービスで失敗したが、自側に通知が届かず
タイムアウト超過待機時間を設定せず無限待ち
手動介入した履歴が残らない業務担当者が DB 直接更新でお茶を濁す

対策

対策内容
タイムアウト設定全 Step にタイムアウトを設け、超過したら補償か TimedOut 状態へ
手動復旧 APIゾンビ化した Saga を安全に再開・キャンセルする API を用意
全イベントをログに手動介入も Saga のイベントとして記録
監視ダッシュボード長時間 Running な Saga を可視化

AI に運用を任せるには、 「ゾンビ Saga はどう扱う?」 の回答を最初から設計に組み込む。

⚡ CES が効く場面 / 過剰な場面

効く場面

  • マイクロサービス間で長期トランザクションが必要
  • 業務上「失敗」が日常的に起こる(在庫切れ・決済失敗・配送不可)
  • 監査要件が厳しく、すべての出来事を追跡可能にしたい
  • 複数チャネル(モール・店頭・倉庫)で在庫やステータスを同期する

過剰な場面

  • 単一 DB で完結する CRUD 主体の業務
  • 結果整合性を業務側が許容できない領域(金融トレード当日決済など)
  • チームに DDD・イベントソーシング・分散トランザクションの運用知見が薄い段階
  • プロトタイプ・小規模 MVP

CES は 投資対効果の閾値が高い 設計スタイル。AI 駆動開発で速く作れるからといって、小規模案件に持ち込むと運用で疲弊する。

⚠️ CES 採用時のアンチパターン

1. Choreography で 10 サービス連携

イベントの因果関係が追えなくなり、トラブル時の調査が不可能に。

是正: 4 サービス以上なら Orchestration に倒す。または Bounded Context を切り直して Saga を小さく保つ。

2. 補償を後回しに設計

「まず順方向を完成させて、補償は後で」で本番投入。失敗が日常発生して人手で巻き戻す羽目に。

是正: 順方向と補償は セットで設計 。AI に補償だけ別指示で必ず実装させる。

3. Saga に同期 RPC を多用

結局 2PC と同じ可用性問題が発生。

是正: Saga 内は イベント駆動 。同期 RPC が必要ならその部分だけ切り出し、Saga の中には置かない。

4. Idempotency の欠落

同じイベントが 2 回届くと状態が壊れる。

是正: 各 Step で Idempotency Key を持たせ、重複検出を標準装備。AI に「Idempotency を保証して」と明示。

📚 まとめ

  • CES は Command + Event + Saga を組み合わせ、長期トランザクションを明示的にモデリングする 設計スタイル
  • AI 駆動開発では 「成功と失敗の両シナリオを自動で認識できる」 のが最大の効用
  • Saga のスタイルは Choreography(疎結合) vs Orchestration(集中制御) 。4 サービス以上は Orchestration 推奨
  • 補償トランザクションは 業務イベントで表現 。取り消せないアクションは後続フローで対応
  • ゾンビ Saga 対策(タイムアウト・手動復旧 API・監視)を 最初から設計 に組み込む
  • 投資対効果の閾値が高い。単純 CRUD には過剰

🔗 関連記事

📖 関連用語