ウィキペディアから(これについてのすばらしい詳細な例があります):
トランザクションの過程で行が2回取得され、行内の値が読み取り間で異なる場合、繰り返し不可能な読み取りが発生します。
および
ファントム読み取りは、トランザクションの過程で2つの同一のクエリが実行され、2番目のクエリによって返される行のコレクションが最初のクエリと異なる場合に発生します。
簡単な例:
- ユーザーAは同じクエリを2回実行します。
- その間に、ユーザーBがトランザクションを実行してコミットします。
- 繰り返し不可の読み取り:ユーザーAがクエリしたA行の値が2回目に異なります。
- ファントム読み取り:クエリ内のすべての行の前後の値は同じですが、異なる行が選択されています (Bが一部を削除または挿入したため)。例:
select sum(x) from table;
影響を受ける行自体が更新されていない場合でも、行が追加または削除されている場合は、異なる結果が返されます。
上記の例では、どの分離レベルを使用しますか?
必要な分離レベルは、アプリケーションによって異なります。 「より良い」分離レベル(同時実行性の低下など)には高いコストがかかります。
この例では、単一の行(主キーで識別される)からのみ選択するため、ファントムの読み取りは行われません。繰り返し不可能な読み取りを行うことができるため、それが問題になる場合は、それを防ぐ分離レベルが必要になる場合があります。 Oracleでは、トランザクションAがSELECT FOR UPDATEを発行することもでき、トランザクションBはAが完了するまで行を変更できません。