はじめに
Non-repeatable ReadとPhantom Readに関して、違いがわからなかったので整理しました。
どちらも同じトランザクション間で2回の同じデータ取得を行う際に、その間で別トランザクションでデータ更新が加わったとき、データをの整合性が取れなくなるという点で似ていると感じました。
違い
主に違いはデータ取得の対象です。
Non-repeatable Readは同じ行に対する取得を対象としていますが、Phantom Readに関してはある一定の範囲を対象としています。ある一定の範囲はクエリでの検索対象となる範囲です。
Non-repeatable Read | Phantom Read | |
---|---|---|
対象 | 同じ行 | 特定の検索条件に一致する範囲 |
シナリオ | 同じトランザクション内で、同じ行を2回読み取った際に異なる結果が返される | 同じトランザクション内で、1回目と2回目の検索で、行の数や内容が変わる |
原因 | 他のトランザクションによる対象の行データの更新 | 他のトランザクションによる行の挿入や削除 |
防げる分離レベル | Repeatable Read以上 | Serializableのみ |
例 |
①: トランザクションA内で商品Aの価格を取得する。商品Aは100円。 ②: トランザクションBが商品Aの価格を120円に更新し、コミットする。 ③: トランザクションAが再度商品Aの価格を取得する。商品Aは120円となってしまう。 |
①: トランザクションAが「価格が100円以上の商品」を検索し、商品A(100円)と商品B(120円)を取得する。 ②: トランザクションBが商品C(価格110円)を挿入し、コミットする。 ③: トランザクションAが再度同じ条件で検索すると、商品Aと商品Bに加えて商品Cも結果に含まれてしまう. |