Dual Write Problem
二重書き込み問題
「1つの操作で、2つの異なるデータストアに書き込まなければならない」ときに、
片方だけ成功してもう片方が失敗すると、データの整合性が壊れる、という問題のこと
典型的な例
注文を受け付けたら、DBに保存して、さらにメッセージキュー(Kafka等)にイベントを流すという処理を考える
DB保存だけ成功したパターン
code:_
1. DB に order を INSERT ← 成功
2. Kafka に OrderCreated を publish ← 失敗💥
DBには注文があるのに、Kafkaにはイベントが流れていない
→ 下流のサービス(在庫、決済、通知など)が注文の存在を知らないまま
メッセージキューだけ成功したパターン
code:_
1. Kafka に publish ← 成功
2. DB に INSERT ← 失敗💥
イベントは流れたのに、DBには注文が無い
なぜ単純に解決できないのか
DBとメッセージキューは別システムなので、両者をまたぐ単一トランザクションが張れない
理論上は2-Phase Commitで組めるが、
多くのモダンなミドルウェア(Kafka等)が対応していない、または非推奨
性能が悪い、運用が複雑、コーディネータが単一障害点になる
という理由で、実務ではほとんど使われませんClaude Code.icon
そうなんやmrsekut.icon
さらに厄介なのが部分的失敗の曖昧さもある
「publishした」と思ったらレスポンスが返る前にタイムアウトした場合、本当に成功したのか失敗したのか分からない
リトライすれば二重送信になるかもしれない
主な解決策
Outboxパターン
CDC
Event Sourcing
Listen to Yourself
先にイベントを発行し、自分自身もそのイベントを購読してDBを更新する
書き込み先が実質Kafka1つになる