- Mở song song hai kết nối, như hai bản sao của
psql
hoặc hai cửa sổ truy vấn trong pgAdmin (mỗi cửa sổ có phiên riêng). - Bắt đầu giao dịch trong mỗi kết nối.
BEGIN;
- Lần lượt chạy các lệnh xung đột lẫn nhau.
- Trước khi bạn có thể cam kết, một trong hai điều đó sẽ được khôi phục với ngoại lệ bế tắc.
- Bạn có thể muốn quay trở lại cái khác.
ROLLBACK;
Rõ ràng khóa bảng đơn giản như:
LOCK tbl;
Khóa các hàng có thể được thực hiện với:
SELECT * FROM tbl WHERE boo = 3 FOR UPDATE;
Hoặc FOR SHARE
v.v. Chi tiết trong sách hướng dẫn.
(Hoặc ngầm hiểu với UPDATE
hoặc DELETE
.)
Ví dụ
Ví dụ đã thêm của bạn không thể bế tắc. Cả hai cố gắng lấy cùng một ổ khóa trên cùng một hàng của cùng một bảng trước. Cái thứ hai sẽ đợi cái thứ nhất kết thúc.
Ví dụ để thực sự tạo ra một khóa chết (các hàng phải tồn tại hoặc không có khóa nào sẽ được sử dụng):
Transaction 1 Transaction 2
BEGIN;
BEGIN;
SELECT salary1
FROM deadlock_demonstration
WHERE worker_id = 1
FOR UPDATE;
SELECT salary1
FROM deadlock_demonstration
WHERE worker_id = 2
FOR UPDATE;
UPDATE deadlock_demonstration
SET salary1 = 100
WHERE worker_id = 2;
UPDATE deadlock_demonstration
SET salary1 = 100
WHERE worker_id = 1;
--> ... 💣 deadlock!
Kết quả
Người dùng OP3388473 đã đóng góp ảnh chụp màn hình này sau khi xác minh giải pháp: