W artykule z 1995 r. Krytyka poziomów izolacji ANSI SQL , Jim Gray i spółka, opisali Phantom Read jako:
Dlatego odczyt fantomowy nie oznacza, że możesz po prostu zwrócić migawkę z początku bieżącej transakcji i udawać, że dostarczenie tego samego wyniku dla zapytania ochroni cię przed faktyczną anomalią odczytu fantomowego.
W oryginalnej implementacji SQL Server 2PL (Two-Phase Locking) zwracanie tego samego wyniku dla kwerendy implikowanej Predicate Locks.
Izolacja migawek MVCC (Multi-Version Concurrency Control) (błędnie nazwana Serializable w Oracle) w rzeczywistości nie uniemożliwia innym transakcjom wstawiania/usuwania wierszy spełniających te same kryteria filtrowania z zapytaniem, które zostało już wykonane i zwróciło zestaw wyników w naszym bieżącym uruchomieniu transakcja.
Z tego powodu możemy sobie wyobrazić następujący scenariusz, w którym chcemy zastosować podwyżkę dla wszystkich pracowników:
- 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:
W tym scenariuszu CEO przeprowadza pierwszą transakcję (Tx1), więc:
- Najpierw sprawdza sumę wszystkich wynagrodzeń w swojej firmie.
- Tymczasem dział HR przeprowadza drugą transakcję (Tx2), ponieważ właśnie udało im się zatrudnić Johna Doe i dać mu pensję w wysokości 100 000 USD.
- Dyrektor generalny decyduje, że podwyżka o 10% jest możliwa, biorąc pod uwagę całkowitą sumę wynagrodzeń, nie wiedząc, że suma wynagrodzeń wzrosła o 100 tys.
- Tymczasem transakcja HR Tx2 jest zatwierdzona.
- Tx1 jest zadeklarowany.
Bum! Dyrektor generalny podjął decyzję w sprawie starej migawki, dając podwyżkę, która może nie zostać utrzymana przy obecnym zaktualizowanym budżecie wynagrodzeń.
Możesz zobaczyć szczegółowe wyjaśnienie tego przypadku użycia (z dużą ilością diagramów) w następującym poście .
Czy to jest odczyt widmowy, czy Pochylenie zapisu ?
Według Jim Gray i współ , jest to odczyt widmowy, ponieważ pochylenie zapisu jest zdefiniowane jako:
W Oracle Menedżer transakcji może, ale nie musi, wykryć powyższą anomalię, ponieważ nie używa blokad predykatów lub Blokady zakresu indeksu (blokady następnego klawisza) , jak MySQL.
PostgreSQL udaje się wyłapać tę anomalię tylko wtedy, gdy Bob wykona odczyt tabeli pracowników, w przeciwnym razie zjawisko to nie zostanie powstrzymane.
AKTUALIZACJA
Początkowo zakładałem, że Serializability będzie również oznaczać zamawianie czasu. Jednak, jak bardzo dobrze wyjaśnił Peter Bailis , zamawianie zegara ściennego lub linearyzacja są zakładane tylko dla ścisłej serializacji.
Dlatego moje założenia zostały poczynione dla systemu Strict Serializable. Ale nie to ma oferować Serializable. Model izolacji z możliwością serializacji nie daje żadnych gwarancji dotyczących czasu, a operacje można zmieniać, o ile są równoważne z niektórymi seryjne wykonanie.
Dlatego, zgodnie z definicją Serializable, taki Phantom Read może wystąpić, jeśli druga transakcja nie spowoduje żadnego odczytu. Ale w modelu Strict Serializable, oferowanym przez 2PL, Phantom Read byłby uniemożliwiony, nawet jeśli druga transakcja nie spowoduje odczytu dla tych samych wpisów, które staramy się chronić przed fantomowymi odczytami.