アウトボックスパターン あうとぼっくすぱたーん
簡単に言うとこんな感じ!
「DBを更新したのにメッセージ送信が失敗して、データがバラバラ…」という事故を防ぐ仕組みだよ! 更新内容を一旦「送信待ちトレイ(アウトボックス)」にまとめて保存しておいて、あとでまとめて送り出すってこと!
アウトボックスパターンとは
アウトボックスパターン(Transactional Outbox Pattern)とは、データベースの更新とメッセージの送信を確実に一致させるためのアーキテクチャパターンです。システムがデータを保存すると同時に外部へ通知(メッセージ)を送る必要がある場面で、「保存は成功したのに通知が届かなかった」「通知は飛んだのにDBが更新されていなかった」といった矛盾(不整合)を防ぎます。
マイクロサービス構成やイベント駆動アーキテクチャでは、複数のシステムがメッセージキューやイベントバスを介して連携します。このとき「DBへの書き込み」と「メッセージの送信」を別々に行うと、どちらか一方が失敗するリスクがあります。これを二重書き込み問題(Dual Write Problem)と呼びます。アウトボックスパターンはこの問題を解決するための標準的な手法として広く採用されています。
具体的には、「送るべきメッセージ」をいったんアプリケーションと同じデータベースの専用テーブル(アウトボックステーブル)に書き込み、別のプロセスがそれを読み取って実際にメッセージを配信します。DBへの書き込みとアウトボックステーブルへの書き込みを同一トランザクション内で行うことで、両者の整合性が保証されます。
アウトボックスパターンの仕組み
処理の流れ
| ステップ | 実行内容 | ポイント |
|---|---|---|
| ① アプリが更新 | 業務データを更新し、同一DBのアウトボックステーブルにメッセージを書き込む | 同一トランザクションで実施 |
| ② コミット | トランザクションが成功すれば両方が確実に保存される | 失敗すれば両方ロールバック |
| ③ 配信プロセスが読取 | アウトボックステーブルを監視し、未送信メッセージを取得 | 別プロセス・非同期で動作 |
| ④ メッセージを送信 | メッセージキュー(Kafkaなど)や他サービスへ配信 | 失敗しても再試行可能 |
| ⑤ 送信済みマーク | 送信が完了したレコードを削除 or ステータス更新 | 冪等性に注意 |
配信プロセスの実現方法
配信プロセス(アウトボックスを読んで送り出す役割)には主に2種類のアプローチがあります。
- ポーリング方式:定期的にアウトボックステーブルをSELECTして未送信メッセージを取得する。実装がシンプルで導入しやすい。
- CDCベース方式:CDC(Change Data Capture)と呼ばれる技術でDBのログ(WAL)を監視し、変更をリアルタイムに検知する。Debezium などのOSSが代表例。
覚え方
「手紙は一旦アウトボックスに入れてから郵便屋さんに渡す」と覚えよう! 書いた手紙(メッセージ)を直接ポスト(キュー)に投げ込むのではなく、デスクのトレイ(アウトボックス)にしまってから、郵便屋さん(配信プロセス)が後でまとめて持っていく。書いた瞬間に消えても、トレイに入っていれば再配達できる!
歴史と背景
- 2000年代〜:SOA(サービス指向アーキテクチャ)の普及とともに、サービス間のデータ整合性問題が顕在化。分散トランザクション(2PC)が主流だったが、性能・可用性の課題が大きかった
- 2010年代前半:マイクロサービスアーキテクチャの概念が広まり、各サービスが独立したDBを持つ設計(Database per Service パターン)が一般化。これにより二重書き込み問題が急増
- 2015年頃:Chris Richardsonがマイクロサービスパターンを体系化し、Transactional Outbox Patternとして広く紹介。microservices.io で公式パターンとして掲載
- 2017年〜:KafkaやRabbitMQなどのメッセージブローカーが普及し、アウトボックスパターンとの組み合わせが定番化
- 2019年〜:DebeziumなどのCDCツールが成熟し、ポーリングに代わるCDCベースの実装が主流になりつつある
- 現在:クラウドネイティブ・マイクロサービス設計の必須パターンとして、AWS・Azure・GCPのリファレンスアーキテクチャにも登場
関連する技術・パターンとの比較
アウトボックスパターン vs 他の整合性確保手法
| 手法 | 概要 | メリット | デメリット |
|---|---|---|---|
| アウトボックスパターン | DB更新と同一トランザクションでメッセージを一時保存 | 確実な整合性・実装がシンプル | アウトボックステーブルの管理が必要 |
| 2フェーズコミット(2PC) | 複数DBを一括でコミット | 強整合性 | 性能劣化・可用性低下のリスク大 |
| SAGAパターン | 分散トランザクションを補償トランザクションで対処 | サービス独立性を保てる | ロールバックロジックが複雑 |
| 直接メッセージ送信 | DB更新後に即座にキューへ送信 | 実装が最もシンプル | 二重書き込み問題が発生しうる |
アウトボックスパターンの構造(SVG図解)
冪等性への対応
配信プロセスは失敗時に再試行するため、同じメッセージが複数回送られる可能性があります。受け取り側が冪等(べきとう)—何度受け取っても同じ結果になる—設計であることが重要です。実務では、メッセージIDで重複チェックを行うのが一般的です。
関連用語
- マイクロサービス — アプリを小さな独立したサービスに分割するアーキテクチャスタイル
- SAGAパターン — 分散トランザクションを補償処理で実現するパターン
- イベント駆動アーキテクチャ — イベントの発生を起点にシステムを連携させる設計手法
- メッセージキュー — サービス間でメッセージを非同期に受け渡す仕組み
- CDC(Change Data Capture) — DBのログを監視してデータ変更をリアルタイム検知する技術
- 結果整合性 — 即時ではなく最終的にデータが一致することを保証する考え方
- トランザクション — 複数の処理をひとまとまりとして扱い、全部成功か全部失敗かを保証する仕組み
- Debezium — OSSのCDCプラットフォーム。アウトボックスパターンの配信プロセス実装によく使われる