【ふぁんとむりーど】

ファントムリード とは?

最終更新:
💡 同じ検索条件なのに、該当する行が変わる

同じトランザクション内で検索条件を変えずに再実行したとき、別のトランザクションのコミット済み変更により、条件を満たす行の集合が変わる現象。行数が同じでも、該当する行が入れ替わる場合がある。

📌 このページのポイント
ファントムリード:行集合が変化 A:同じトランザクション内の検索 東京支店の社員 田中 / 佐藤 ① 2人 東京支店の社員 田中 / 佐藤 鈴木を追加 ③ 3人 ② 別トランザクションB 鈴木をINSERT → COMMIT 両方とも同じ検索条件 東京支店の社員を取得 行数が同じでも、集合が変わる場合も 防止方法は分離レベルとDBMSに依存
別トランザクションが確定した挿入を2回目の検索で読む例(例:PostgreSQLのRead Committed)。矢印は検索順とBの変更の反映を示す。Repeatable Read等で必ず発生する図ではない。
ひよこ ひよこ
ファントムリードって、何が変わるの?
ペンギン先生 ペンギン先生
同じトランザクションで、例えば東京支店の社員をもう一度検索したとき、別のトランザクションの確定済み変更が見えて、該当する行が変わることだよ。社員が追加されて2人から3人になるのは一つの例なんだ。
ひよこ ひよこ
行数が同じなら問題は起きていない?
ペンギン先生 ペンギン先生
行数だけでは判断できないよ。誰かが別の支店へ移り、別の人が東京へ移れば、2人のままでも該当する社員は入れ替わる。INSERTやDELETEだけでなく、条件に関係するUPDATEでも集合が変わるんだ。
ペンギン先生 ペンギン先生
ダーティリードは未確定の変更を読んでしまうこと。ノンリピータブルリードは読んだ行を再読したら変更されていること。ファントムリードでは、同じ検索条件に該当する行の集合が変わることに注目するよ。
ひよこ ひよこ
Repeatable Readでも起きるの?
ペンギン先生 ペンギン先生
SQL標準では許されるけれど、DBMSによるよ。PostgreSQLのRepeatable Readでは防げる。Serializableでも防げるが、競合でトランザクションが失敗して再試行が必要になる場合がある。名前だけで判断せず、使うDBの仕様を確かめよう。
ひよこ ひよこ
MySQLでは、全部ギャップロックで防ぐの?
ペンギン先生 ペンギン先生
InnoDBのRepeatable Readで通常のSELECTを繰り返す場合は、同じスナップショットを読む仕組みで、読み取りによるロックはかけないよ。FOR UPDATEなどのロック付き読み取りでは、索引の行とその前の隙間を守るネクストキーロックが関係する。分離レベルや検索方法によってロック範囲は変わるんだ。
ペンギン
まとめ:ざっくりこれだけ覚えればOK!
「ファントムリード」って出てきたら「同じトランザクションで同じ条件を検索しても、該当する行が変わる現象」と思えばだいたいOK!
📖 おまけ:英語の意味
「Phantom Read」 = 幽霊読み取り
💬 phantom(幽霊)のように、突然現れたり消えたりする行のことだよ

参考資料

← 用語集にもどる