要点: 複数サービスにまたがる業務では、共有ロックではなく、再開できるワークフローが信頼性を作ります。
この記事の用語: Saga:複数ステップと補償処理からなるワークフロー。補償処理:完了済みステップの影響を業務的に取り消す処理。
現場の課題
決済、在庫確保、配送は一つのDBトランザクションにできません。応答を失っても処理済みの場合があり、続行、再試行、補償のどれを行うか判断できる設計が必要です。
共通トランザクションがないため、各ステップは応答を失っても成功済みかもしれません。Sagaは状態を保存し、再試行可能な操作と補償処理、人の判断が必要な状態を区別します。
設計と実装
- 各ステップを実装する前に、業務状態、期限、終了条件を定義します。
- ステップごとに安定した操作IDを持たせ、再試行時は既存結果を照会します。
- 補償処理も独立した業務操作として、状態と監査ログを管理します。
実装例
workflow.save(state = 'RESERVING', version = 4)
reservation = inventory.reserve(orderId, operationId)
workflow.save(state = 'CHARGING', reservationId)
charge = payments.charge(orderId, operationId)
workflow.save(state = 'CONFIRMED', chargeId)本番導入の進め方
新ワークフローを既存経路の横で観測だけに使い、履歴を比較します。ステップを一つずつ移し、重複、サービス停止、再起動の訓練が通るまで照合レポートを残します。
まとめ
良いSagaは途中状態を見えるようにし、再開できます。分散システムを原子的に見せかけません。
