🤖

Web+DBシステムでの読み取り整合性の問題とそれが発生しうる3つのレベルの話

2025/02/26に公開

DBを含んだWebシステムを構築するとき、書き込んだ直後の結果を読み取ろうとすると問題が起こるケースがあります(いわゆる読み取り整合性の問題)。
このページではそれを整理しています。

※ 経験ベースで一旦列挙したものなので、網羅しきれていなかったり見落としがあるかも

番号が若いほどミクロよりです。

1. DBトランザクションレベル

いわゆるDBのトランザクション分離レベルに関連した話。

dirty read, phantom readなどと言った問題を引き起こします。

これはDBインスタンスが1台のみでレプリケーションを行っていない場合でも発生する問題です。

2. DBクラスターレベル

レプリケーションを行っているDBクラスターで発生する問題です。
こんな感じ:

  1. マスターインスタンスへinsert
  2. スレーブインスタンスでその結果をselect
  3. マスターからスレーブへレプリケーションされる前にselectされた結果、insertした結果が取れない

この問題はレプリケーション設定がある場合のみ問題が発生します。レプリケーション自体が比較的近年多用されるようになったためか、トランザクション分離レベルほど十分な議論がされていません。

これについては、次のような対策が考えられています:

3. リクエストレベル

ウェブアプリケーションで発生する問題です。
こんな感じ:

  1. クライアントからPOSTやPUTリクエストを通じてDBへ書き込む
  2. クライアントからGETリクエストを通じてDBから読み取る
  3. マスターからスレーブへレプリケーションされる前にselectされた結果、insertした結果が取れない

これは前述のstickyオプションなどでは解決できません。

これについては次のような対策が考えられています:

まとめ

Web+DBシステムでの読み取り整合性の問題とそれが発生しうる3つのレベルを紹介しました。

  1. DBトランザクションレベル
  2. DBクラスターレベル
  3. リクエストレベル

重要な点として、これらは前者ほどミクロ、後者ほどマクロではあるものの、どれかを対応すれば他に対応する必要がない、というものではない点です。
リクエストレベルで対応したとしてもDBクラスターレベルで整合性に配慮しないと、問題が発生します。
よりよい機能リリースを目指すのであれば、これらそれぞれへ配慮した実装が必要となるでしょう。

株式会社エス・エム・エス

Discussion