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

Postgres pg_try_advisory_lock chặn tất cả các bản ghi

Bạn đang gọi pg_try_advisory_lock () một lần cho mỗi hàng trong toàn bộ tập hợp được quét (như một phần của quá trình lọc xảy ra trong where ), trong khi bạn chỉ muốn nó được gọi một lần trên mỗi hàng trong table1 được trả về bởi truy vấn.

Thay vào đó, bạn có thể thử sử dụng truy vấn con hoặc CTE:

with rows as (
SELECT a.id
FROM table1 a
JOIN table2 b ON a.table1_id = b.id
WHERE table2.id = 1
)
select rows.*
from rows
where pg_try_advisory_lock('table1'::regclass::integer, rows.id);

Nhưng đừng dựa vào đó để nhất thiết phải hoạt động như mong đợi:Postgres nên bị cám dỗ để viết lại nó theo cách truy vấn ban đầu của bạn.

Một khả năng khác là điều này, vì select một phần của câu lệnh được đánh giá rất muộn trong truy vấn:

with rows as (
SELECT a.id,
       pg_try_advisory_lock('table1'::regclass::integer, a.id) as locked
FROM table1 a
JOIN table2 b ON a.table1_id = b.id
WHERE table2.id = 1
)
select rows.id
from rows
where rows.locked;

Vấn đề thực sự trong thực tế là pg_try_advisory_lock() là thứ mà bạn thường tìm thấy trong vùng đất ứng dụng hoặc trong một chức năng, thay vì trong một truy vấn như bạn đang làm. Nói về điều này, tùy thuộc vào những gì bạn đang làm, bạn có chắc chắn không nên sử dụng select … for update ?

Về bản cập nhật của bạn:

Đúng. Do limit 1 , nó sẽ tìm thấy một kết hợp và ngay lập tức dừng lại. Tuy nhiên, điều có thể đang xảy ra là nó không đánh giá where mệnh đề theo thứ tự tương tự tùy thuộc vào truy vấn của bạn. SQL không đảm bảo rằng a <> 0 một phần trong a <> 0 and b / a > c được đánh giá đầu tiên. Được áp dụng cho trường hợp của bạn, nó không đảm bảo rằng khóa tư vấn có được sau hàng từ a được nối với b.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Postregsql Ngày Chênh lệch trên cơ sở tính theo giây

  2. Postgres 9.4:Bao gồm cột anh chị em trong mỗi kết quả mảng jsonb

  3. Rails không thể đăng nhập vào postgresql - PG ::Lỗi - mật khẩu - Thông tin chính xác

  4. Postgres ĐỂ LOOP

  5. Ràng buộc khóa ngoại kết hợp đa hình. Đây có phải là một giải pháp tốt?