Một cách để đối phó với các bế tắc là có một cơ chế thử lại chờ một khoảng thời gian ngẫu nhiên và cố gắng chạy lại giao dịch. Khoảng thời gian ngẫu nhiên là cần thiết để các giao dịch va chạm không liên tục va chạm vào nhau, gây ra cái được gọi là khóa trực tiếp - một thứ thậm chí còn tệ hơn để gỡ lỗi. Trên thực tế, hầu hết các ứng dụng phức tạp sẽ sớm hoặc muộn cần cơ chế thử lại như vậy khi chúng cần xử lý các lỗi tuần tự hóa giao dịch.
Tất nhiên, nếu bạn có thể xác định được nguyên nhân gây ra bế tắc thì thường tốt hơn nhiều là bạn nên loại bỏ nó hoặc nó sẽ quay lại cắn bạn. Đối với hầu hết các trường hợp, ngay cả khi tình trạng khóa chết hiếm khi xảy ra, thì một chút thông lượng và chi phí mã hóa để có được các khóa theo thứ tự xác định hoặc nhận được nhiều khóa chi tiết hơn là điều đáng giá để tránh việc thỉnh thoảng gặp phải độ trễ lớn và hiệu suất đột ngột. khi mở rộng quy mô đồng thời.
Khi bạn liên tục nhận được hai câu lệnh INSERT bị khóa, rất có thể đó là sự cố về thứ tự chèn chỉ mục duy nhất. Hãy thử làm ví dụ như sau trong hai cửa sổ lệnh psql:
Thread A | Thread B
BEGIN; | BEGIN;
| INSERT uniq=1;
INSERT uniq=2; |
| INSERT uniq=2;
| block waiting for thread A to commit or rollback, to
| see if this is an unique key error.
INSERT uniq=1; |
blocks waiting |
for thread B, |
DEADLOCK |
V
Thông thường, hành động tốt nhất để giải quyết vấn đề này là tìm ra các đối tượng mẹ bảo vệ tất cả các giao dịch như vậy. Hầu hết các ứng dụng có một hoặc hai thực thể chính, chẳng hạn như người dùng hoặc tài khoản, là những ứng cử viên tốt cho việc này. Sau đó, tất cả những gì bạn cần là cho mọi giao dịch để có được các khóa trên thực thể chính mà nó chạm vào thông qua CHỌN ... ĐỂ CẬP NHẬT. Hoặc nếu chạm vào một số khóa, hãy lấy khóa trên tất cả chúng nhưng theo thứ tự giống nhau mọi lúc (thứ tự theo khóa chính là một lựa chọn tốt).