Trong bài báo năm 1995, Phê bình về mức độ cách ly ANSI SQL Jim Gray và cộng sự đã mô tả Phantom Read là:
Do đó, Phantom Read không có nghĩa là bạn chỉ có thể trả lại ảnh chụp nhanh kể từ khi bắt đầu giao dịch hiện đang chạy và giả vờ rằng việc cung cấp cùng một kết quả cho một truy vấn sẽ bảo vệ bạn khỏi sự bất thường thực tế của Phantom Read.
Trong triển khai SQL Server 2PL (Khóa hai pha) ban đầu, trả về cùng một kết quả cho một truy vấn ngụ ý Khóa dự đoán.
Cách ly ảnh chụp nhanh MVCC (Multi-Version Concurrency Control) (được đặt tên sai là Serializable trong Oracle) không thực sự ngăn các giao dịch khác chèn / xóa các hàng khớp với cùng tiêu chí lọc với một truy vấn đã được thực thi và trả về kết quả được đặt trong quá trình chạy hiện tại của chúng tôi giao dịch.
Vì lý do này, chúng ta có thể hình dung tình huống sau đây mà chúng ta muốn áp dụng tăng lương cho tất cả nhân viên:
- 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:
Trong trường hợp này, Giám đốc điều hành chạy giao dịch đầu tiên (Tx1), do đó:
- Đầu tiên, cô ấy kiểm tra tổng số tiền lương trong công ty của mình.
- Trong khi đó, bộ phận nhân sự thực hiện giao dịch thứ hai (Tx2) vì họ vừa thuê được John Doe và trả cho anh ấy mức lương 100k đô la.
- Giám đốc điều hành quyết định rằng việc tăng 10% là khả thi khi tính đến tổng số tiền lương, nhưng không biết rằng số tiền lương đã tăng là 100k.
- Trong khi đó, giao dịch nhân sự Tx2 được cam kết.
- Tx1 được cam kết.
Bùm! Giám đốc điều hành đã đưa ra quyết định dựa trên một ảnh chụp nhanh cũ, đưa ra mức tăng lương mà ngân sách tiền lương cập nhật hiện tại có thể không duy trì được.
Bạn có thể xem giải thích chi tiết về trường hợp sử dụng này (với nhiều sơ đồ) trong bài đăng sau .
Đây là Phantom Read hay Viết Skew ?
Theo Jim Gray và đồng , đây là Phantom Read vì Write Skew được định nghĩa là:
Trong Oracle, Trình quản lý giao dịch có thể phát hiện ra điều bất thường ở trên vì nó không sử dụng khóa vị từ hoặc ổ khóa phạm vi chỉ mục (ổ khóa tiếp theo) , như MySQL.
PostgreSQL quản lý để phát hiện sự bất thường này chỉ khi Bob đưa ra một kết quả đọc đối với bảng nhân viên, nếu không, hiện tượng này sẽ không được ngăn chặn.
CẬP NHẬT
Ban đầu, tôi đã giả định rằng Khả năng nối tiếp cũng sẽ ngụ ý một thứ tự thời gian. Tuy nhiên, như Peter Bailis giải thích rất rõ , đặt hàng đồng hồ treo tường hoặc Khả năng phân biệt tuyến tính chỉ được giả định cho Khả năng tuần tự nghiêm ngặt.
Do đó, các giả định của tôi đã được thực hiện cho một hệ thống Có thể nối tiếp nghiêm ngặt. Nhưng đó không phải là những gì Serializable được cho là cung cấp. Mô hình cách ly Serializable không đảm bảo về thời gian và các hoạt động được phép sắp xếp lại miễn là chúng tương đương với một số thực hiện nối tiếp.
Do đó, theo định nghĩa Serializable, một Phantom Read như vậy có thể xảy ra nếu giao dịch thứ hai không thực hiện bất kỳ lần đọc nào. Tuy nhiên, trong mô hình Có thể nối tiếp nghiêm ngặt, mô hình được cung cấp bởi 2PL, Phantom Read sẽ bị ngăn chặn ngay cả khi giao dịch thứ hai không đưa ra kết quả đọc đối với các mục nhập tương tự mà chúng tôi đang cố gắng bảo vệ chống lại các lần đọc ảo.