1. ホーム
  2. データベース

[解決済み】Non-Repeatable ReadとPhantom Readの違いは何ですか?

2022-04-14 18:06:05

質問

ノンリピートリードとファントムリードの違いは何ですか?

を読みました。 ウィキペディアの「分離 (データベースシステム)」の記事 しかし、私はいくつかの疑問があります。以下の例では、どうなるのでしょうか? 繰り返し不可能な読み取り ファントムリード ?

トランザクションA
SELECT ID, USERNAME, accountno, amount FROM USERS WHERE ID=1

OUTPUTです。
1----MIKE------29019892---------5000

トランザクションB
UPDATE USERS SET amount=amount+5000 where ID=1 AND accountno=29019892;
COMMIT;

トランザクションA
SELECT ID, USERNAME, accountno, amount FROM USERS WHERE ID=1

もう一つの疑問は、上記の例で、どの分離レベルを使うべきか?そしてその理由は?

解決方法は?

ウィキペディアより (これについては、素晴らしい詳細な例があります)。

<ブロッククオート

トランザクションの過程で、1つの行が2回取得され、その行の値が読み取りのたびに異なる場合、「非再現性読み取り」が発生します。

そして

トランザクションの過程で、2つの同一のクエリが実行され、2番目のクエリが返す行のコレクションが最初のものと異なる場合に、ファントムリードが発生します。

簡単な例です。

  • ユーザーAが同じクエリを2回実行する。
  • その間に、ユーザーBがトランザクションを実行し、コミットする。
  • 再現性のない読み取り。ユーザーAが照会したA行は、2回目には異なる値になっている。
  • ファントムリード。クエリ内のすべての行が、前後で同じ値を持つ。 しかし、異なる行が選択されている (Bが一部を削除または挿入したため)。例 select sum(x) from table; は、影響を受ける行そのものが更新されていなくても、行の追加や削除が行われていれば、異なる結果を返します。
<ブロッククオート

上記の例では、どの分離レベルを使用すればよいのでしょうか?

どのようなアイソレーション・レベルが必要かは、アプリケーションによって異なります。より良い分離レベルには高いコストがかかります(並行性の低下など)。

この例では、(主キーで識別される)1つの行からしか選択しないので、ファントムリードは発生しません。もしそれが問題なら、それを防ぐ分離レベルを設定するとよいでしょう。Oracleでは、トランザクションAはSELECT FOR UPDATEを発行し、トランザクションBはAが終了するまで行を変更することができません。