Im Papier von 1995, Eine Kritik an ANSI-SQL-Isolationsstufen , Jim Gray und Co. beschrieben Phantom Read als:
Daher bedeutet ein Phantom-Lesevorgang nicht, dass Sie einfach einen Snapshot vom Beginn der aktuell laufenden Transaktion zurückgeben und so tun können, als würde Sie das gleiche Ergebnis für eine Abfrage vor der tatsächlichen Phantom-Lese-Anomalie schützen.
In der ursprünglichen Implementierung von SQL Server 2PL (Two-Phase Locking) implizierte die Rückgabe desselben Ergebnisses für eine Abfrage Prädikatsperren.
Die MVCC (Multi-Version Concurrency Control) Snapshot Isolation (in Oracle fälschlicherweise als Serializable bezeichnet) hindert andere Transaktionen nicht wirklich daran, Zeilen einzufügen/zu löschen, die denselben Filterkriterien mit einer Abfrage entsprechen, die bereits ausgeführt wurde und in unserer aktuellen Ausführung eine Ergebnismenge zurückgegeben hat Transaktion.
Aus diesem Grund können wir uns folgendes Szenario vorstellen, in dem wir allen Mitarbeitern eine Gehaltserhöhung gewähren wollen:
- 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:
In diesem Szenario führt der CEO die erste Transaktion (Tx1) aus, also:
- Sie prüft zunächst die Summe aller Gehälter in ihrem Unternehmen.
- In der Zwischenzeit führt die Personalabteilung die zweite Transaktion (Tx2) durch, da sie es gerade geschafft hat, John Doe einzustellen und ihm ein Gehalt von 100.000 $ zu zahlen.
- Der CEO entscheidet, dass eine Erhöhung um 10 % unter Berücksichtigung der Gesamtsumme der Gehälter möglich ist, ohne zu wissen, dass die Gehaltssumme um 100.000 gestiegen ist.
- In der Zwischenzeit wird die HR-Transaktion Tx2 festgeschrieben.
- Tx1 ist festgeschrieben.
Boom! Der CEO hat eine Entscheidung zu einer alten Momentaufnahme getroffen und eine Gehaltserhöhung gegeben, die möglicherweise nicht durch das aktuelle aktualisierte Gehaltsbudget aufrechterhalten werden kann.
Eine ausführliche Erläuterung dieses Anwendungsfalls (mit vielen Diagrammen) finden Sie im folgenden Beitrag .
Ist dies ein Phantom Read oder ein Versatz schreiben ?
Laut Jim Gray und co , dies ist ein Phantomlesevorgang, da der Schreibversatz wie folgt definiert ist:
In Oracle kann der Transaktionsmanager die obige Anomalie erkennen oder auch nicht, da er keine Prädikatsperren oder Indexbereichssperren (nächste Tastensperre) , wie MySQL.
PostgreSQL kann diese Anomalie nur erkennen, wenn Bob einen Lesevorgang für die Employee-Tabelle ausführt, andernfalls wird das Phänomen nicht verhindert.
AKTUALISIEREN
Anfangs ging ich davon aus, dass die Serialisierbarkeit auch eine Zeitordnung implizieren würde. Wie jedoch sehr gut erklärt von Peter Bailis , Wall-Clock-Reihenfolge oder Linearisierbarkeit wird nur für Strikte Serialisierbarkeit angenommen.
Daher wurden meine Annahmen für ein streng serialisierbares System getroffen. Aber das ist nicht das, was Serializable bieten soll. Das serialisierbare Isolationsmodell gibt keine Garantien für die Zeit, und Operationen dürfen neu geordnet werden, solange sie einigen entsprechen Serienausführung.
Daher kann gemäß der Serializable-Definition ein solcher Phantom-Lesevorgang auftreten, wenn die zweite Transaktion keinen Lesevorgang ausgibt. Aber in einem streng serialisierbaren Modell, das von 2PL angeboten wird, würde das Phantomlesen verhindert werden, selbst wenn die zweite Transaktion kein Lesen für dieselben Einträge ausgibt, die wir vor Phantomlesevorgängen zu schützen versuchen.