PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

CẬP NHẬT nguyên tử .. CHỌN trong Postgres

Mặc dù gợi ý của Erwin có thể là đơn giản nhất cách để có được hành vi chính xác (miễn là bạn thử lại giao dịch của mình nếu bạn gặp ngoại lệ với SQLSTATE của 40001), các ứng dụng xếp hàng theo bản chất của chúng có xu hướng hoạt động tốt hơn với việc chặn các yêu cầu để có cơ hội đến lượt chúng tại hàng đợi so với việc triển khai PostgreSQL của SERIALIZABLE giao dịch, cho phép đồng thời cao hơn và có phần "lạc quan" hơn về khả năng xảy ra va chạm.

Truy vấn ví dụ trong câu hỏi, như nó viết tắt, trong READ COMMITTED mặc định mức cô lập giao dịch sẽ cho phép hai (hoặc nhiều) kết nối đồng thời cả hai "yêu cầu" cùng một hàng từ hàng đợi. Điều gì sẽ xảy ra là:

  • T1 bắt đầu và đi xa đến mức khóa hàng trong UPDATE giai đoạn.
  • T2 chồng lên T1 về thời gian thực thi và cố gắng cập nhật hàng đó. Nó chặn COMMIT đang chờ xử lý hoặc ROLLBACK của T1.
  • T1 cam kết, đã "xác nhận quyền sở hữu" hàng thành công.
  • T2 cố gắng cập nhật hàng, nhận thấy rằng T1 đã có, tìm kiếm phiên bản mới của hàng, thấy rằng hàng đó vẫn đáp ứng tiêu chí lựa chọn (chỉ là id đó khớp) và cũng "xác nhận quyền sở hữu" hàng.

Nó có thể được sửa đổi để hoạt động chính xác (nếu bạn đang sử dụng phiên bản PostgreSQL cho phép FOR UPDATE mệnh đề trong một truy vấn con). Chỉ cần thêm FOR UPDATE vào cuối truy vấn con chọn id và điều này sẽ xảy ra:

  • T1 bắt đầu và bây giờ sẽ khóa hàng trước khi chọn id.
  • T2 chồng lên T1 về thời gian thực thi và các khối trong khi cố gắng chọn một id, đang chờ COMMIT hoặc ROLLBACK của T1.
  • T1 cam kết, đã "xác nhận quyền sở hữu" hàng thành công.
  • Vào thời điểm T2 có thể đọc hàng để xem id, nó thấy rằng nó đã được xác nhận quyền sở hữu, vì vậy nó sẽ tìm id có sẵn tiếp theo.

Tại REPEATABLE READ hoặc SERIALIZABLE mức cô lập giao dịch, xung đột ghi sẽ gây ra lỗi mà bạn có thể bắt gặp và xác định là lỗi tuần tự hóa dựa trên SQLSTATE và thử lại.

Nếu bạn thường muốn các giao dịch CÓ THỂ XỬ LÝ nhưng bạn muốn tránh thử lại trong khu vực xếp hàng, bạn có thể thực hiện điều đó bằng cách sử dụng khóa cố vấn.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Các tùy chọn đa thai cho PostgreSQL

  2. Truy vấn postgresql giữa các phạm vi ngày

  3. Làm cách nào để khôi phục dữ liệu từ vùng chứa Docker đã bị xóa? Làm thế nào để kết nối lại nó với dữ liệu?

  4. Hiểu các loại ngày và chức năng của PostgreSQL (bằng các ví dụ)

  5. THỰC HIỆN ... Câu lệnh USING trong PL / pgSQL không hoạt động với loại bản ghi?