更新だけ成功する事故を防ぐ、AI業務のOutbox台帳
AIエージェントがCRMを更新した直後に停止し、承認通知だけ届かない。そんな不整合を防ぎたい開発責任者向けに、更新と送信予定を同時に残すOutbox台帳の作り方を示します。
「更新してから通知」を二つの書き込みにしない
DB更新と通知の間でプロセスが落ちると、更新済みなのに通知がない状態が残ります。逆順なら通知だけ届きます。AWSはこれを二重書きの問題として説明しています。[1]
Outbox方式では、業務レコードとイベントを同じDBトランザクションで保存します。別ワーカーがOutboxを読み、送信後に処理済みへ変えます。Microsoftも同一トランザクションと別プロセス配送を示しています。[2]
業務API担当は更新とOutbox挿入まで、基盤担当は配送、再試行、滞留監視までを受け持ちます。入力は業務ID、イベント種別、宛先、配送期限、順序キー、重複排除キーです。
コピーして使うOutboxレコード
event_idは配送先でも重複排除に使い、aggregate_idは同じ案件の順序単位にします。本文にはAIの推論全文ではなく、確定した事実と参照IDだけを入れます。
CREATE TABLE outbox_event (
event_id uuid PRIMARY KEY,
aggregate_id text NOT NULL,
event_type text NOT NULL,
payload_json jsonb NOT NULL,
occurred_at timestamptz NOT NULL,
deliver_by timestamptz NOT NULL,
status text NOT NULL DEFAULT 'pending',
attempt_count integer NOT NULL DEFAULT 0,
next_attempt_at timestamptz NOT NULL,
delivered_at timestamptz
);
業務テーブルとOutbox表を同じトランザクションで更新できない構成では中核が成立しません。CDCを使うなら、DebeziumのようにOutbox表の変更だけをイベントへ変換する仕組みも選べます。[3]
実装は五段階で分ける
- 確定後にイベントを作る。 人の承認や業務ルールを通った内容から
event_idとpayload_jsonを作ります。 - 一回でコミットする。 業務更新とOutbox挿入を行い、片方が失敗したら
ROLLBACKします。 - 別ワーカーで配送する。
pendingかつ送信時刻を迎えた行を少量ずつロックし、通知APIへ送ります。 - 受理後だけ完了にする。
deliveredへ変える前に停止した行は再取得します。 - 受信側で重複を捨てる。 配送は重複し得るため、受信側は処理済み
event_idを記録します。AWSも、Outboxの配送では重複に備えて受信処理を冪等にするよう勧めています。[1]
【仮想例】AIが返品申請を確認し、人が承認した後、申請をapprovedへ変えて顧客へ通知します。同一トランザクションで申請更新とreturn.approvedを保存します。直後に停止しても、再起動したワーカーが配送します。応答後に再送しても、受信側は同じevent_idの二通目を捨てます。完了は「申請がapproved」「Outboxがdelivered」「通知先の処理IDがevent_idと一致」の三点です。
失敗しやすい点と適用境界
送信前にdeliveredへ変えると、停止時に通知が消えます。送信後に更新する設計では重複が起こり得るため、重複排除とセットで実装します。また、同じ案件のイベント順が重要なら、aggregate_idと連番を持たせ、古い版を受信側で拒否します。[1]
pending件数、最古の待ち時間、期限超過件数を監視し、期限超過は削除せず例外キューへ送ります。
一つの業務操作が複数サービスのDB更新をまたぎ、失敗時に予約取消や返金などの補償処理が必要という場合には向きません。その場合はOutboxだけで済ませず、Sagaなどの補償フローを設計します。[1]
明日から使える障害試験
| 障害を入れる位置 | 期待結果 | 合格条件 |
|---|---|---|
| 業務更新の直後 | 全体を取消 | 業務行もOutbox行も残らない |
| コミット直後 | 後で配送 | pending行が再起動後に送られる |
| 通知APIの受理直後 | 重複送信を許容 | 受信側の業務処理は一回だけ |
| 同一案件を連続更新 | 順序を維持 | 古い連番が後から適用されない |
| 配送期限を超過 | 例外へ移す | 無言の削除や成功扱いがない |
まず一つの「状態更新+通知」で五つを自動テストします。Outboxは更新と通知の間の消失点を、追跡できる台帳へ変える仕組みです。
参考資料
- AWS Prescriptive Guidance: Transactional outbox pattern
- Microsoft Azure Architecture Center: Implement the Transactional Outbox pattern
- Debezium Documentation: Outbox Event Router
本記事はAIを活用して作成し、公開前に自動レビューを実施しています。情報の確認日:2026-10-22。
Author
ELYSAI編集部