2011-10-19 8 views
0

私はそれがファントムクエリ...などと呼ばれている理由について混乱していますが、これら3つのクエリを想定します -なぜファントムクエリと呼ばれていますか?

クエリ1

SELECT * FROM users 
WHERE salary BETWEEN 10000 AND 300000; 

リターン2つのレコード。

クエリ2

INSERT INTO users VALUES (3, 'Bob', 270000); 
COMMIT; 

クエリ1再び

SELECT * FROM users 
WHERE salary BETWEEN 10000 AND 30000; 

リターン3を記録。

参照してくださいそれは私にとっては普通のようです。私は彼らが「Phantom read」と呼ばれる理由を理解していません。すべてのトランザクションが異なる時期に起こっているので、常に最新のデータを取得しています。最初に2つのレコードがあり、後で1レコードが挿入されました。再度クエリを実行すると、更新されたデータ、つまり3レコードが取得されます。なぜそれが幻のクエリと呼ばれるのですか?

+1

3つの別々のトランザクションで起きている場合、ファントムではありません。ファントムの問題は、同じトランザクションが範囲問合せを複数回実行し、2つの問合せの間にファントム行が挿入された場合に発生します。 –

答えて

3

純粋に学術的なレベルでは、トランザクションは、トランザクションが開始されたときのデータに基づいてデータベースの一貫した状態を確認する必要があります。それは、それ自身の変更だけを見るべきであり、それ以外は何も表示しないでください

トランザクション1が完了していない限り、コミットされたデータの参照は、トランザクションの開始時に存在しなかった行が表示されるため、ファントム読み取りとみなされます。

この強力な学術的アプローチが常に必要なわけではないため、異なる分離レベルが導入されています。要件に応じて、開発者は実装されているビジネスルールに基づいて必要なレベルを選択できます。

時々、あなたはファントム読み取り、あなたは(ほとんどのDBMSのデフォルトです)READ COMMITTED分離レベルを使用したい、時にはあなたがそれらをしたくない - そして、あなたはSERIALIZABLE分離レベルを使用し

+1

ファントムを防ぐには、 'REPEATABLE READ'ではなく' SERIALIZABLE'が必要です。 –

+0

あなたは正しいです。私は反復不可能な読書とファントム読解を混同していました。 –

1

ファントムは、範囲ロックがある場合に発生読み込みます取引でうまく設定されていません。ここで何が起きるかは、あなたが書いたものです。最初のselectは2行を返し、2番目のselectは3行を返します。
ファントム読み取りは、2つの同一のクエリが実行され、2番目のクエリによって返された行のコレクションが最初のものと異なることを意味します。正しい分離が適用されている場合、同じ行セットが両方の時間に返されます。

関連する問題