1995年の論文では、ANSISQL分離レベルの批評 、ジムグレイと共同で、ファントムリードを次のように説明しました:
したがって、ファントムリードは、現在実行中のトランザクションの開始時点でスナップショットを返すだけで、クエリに同じ結果を提供することで実際のファントムリードの異常から保護できるという意味ではありません。
元のSQLServer2PL(Two-Phase Locking)実装では、クエリに対して同じ結果を返すと、述語ロックが暗黙的に示されます。
MVCC(Multi-Version Concurrency Control)スナップショットアイソレーション(Oracleでは誤ってSerializableという名前)は、他のトランザクションが、現在実行中の結果セットをすでに実行して返したクエリと同じフィルタリング基準に一致する行を挿入/削除することを実際には妨げませんトランザクション。
このため、すべての従業員に昇給を適用する次のシナリオを想像できます。
- Tx1:
SELECT SUM(salary) FROM employee where company_id = 1;
- Tx2:
INSERT INTO employee (id, name, company_id, salary) VALUES (100, 'John Doe', 1, 100000);
- Tx1:
UPDATE employee SET salary = salary * 1.1;
- Tx2:
COMMIT;
- Tx1:
COMMIT:
このシナリオでは、CEOが最初のトランザクション(Tx1)を実行するため、次のようになります。
- 最初に、会社のすべての給与の合計を確認します。
- 一方、HR部門は、John Doeを雇い、彼に10万ドルの給与を与えたばかりなので、2番目のトランザクション(Tx2)を実行します。
- CEOは、給与の合計が10万ドルになったことを知らずに、給与の合計を考慮して10%の昇給が可能であると判断しました。
- その間、HRトランザクションTx2がコミットされます。
- Tx1がコミットされます。
ブーム! CEOは古いスナップショットについて決定を下し、現在の更新された給与予算では維持できない可能性のある昇給を行いました。
このユースケースの詳細な説明(多くの図を含む)は、次の投稿で確認できます。 。
これはファントムリードですか、それともスキューを書く ?
JimGrayによるとと共同 、書き込みスキューは次のように定義されているため、これはファントム読み取りです。
Oracleでは、トランザクションマネージャーは、述語ロックまたはインデックス範囲ロック(next-keyロック) 、MySQLのように。
PostgreSQLは、ボブが従業員テーブルに対して読み取りを発行した場合にのみこの異常をキャッチできます。それ以外の場合、この現象は防止されません。
更新
当初、直列化可能性は時間の順序付けも意味すると想定していました。ただし、PeterBailisによる説明 、壁掛け時計の順序付けまたは線形化可能性は、厳密な直列化可能性に対してのみ想定されます。
したがって、私の仮定は、厳密なシリアル化可能なシステムに対して行われました。しかし、それはSerializableが提供することになっているものではありません。シリアル化可能な分離モデルは時間について保証するものではなく、一部と同等である限り、操作を並べ替えることができます。 シリアル実行。
したがって、Serializableの定義によれば、2番目のトランザクションが読み取りを発行しない場合、このようなファントム読み取りが発生する可能性があります。ただし、2PLによって提供される厳密なシリアル化可能なモデルでは、2番目のトランザクションがファントム読み取りから保護しようとしている同じエントリに対して読み取りを発行しない場合でも、ファントム読み取りは防止されます。