PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Postgres pg_try_advisory_lock блокира всички записи

Извиквате pg_try_advisory_lock() веднъж на ред в целия набор, който се сканира (като част от филтрирането, което се случва в where клауза), докато искате да се извиква само веднъж на ред в таблица1, върната от заявката.

Можете да опитате да използвате подзаявка или 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);

Но не разчитайте и на това, че непременно ще работи според очакванията:Postgres трябва да се изкуши да го пренапише по начина, по който беше първоначалната ви заявка.

Друга възможност е това, тъй като select част от израз се оценява много късно в заявката:

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;

Истинският проблем на практика е, че pg_try_advisory_lock() е нещо, което обикновено бихте намерили в областта на приложението или във функция, а не в заявка, както правите. Говорейки за това, в зависимост от това, което правите, сигурни ли сте, че не трябва да използвате select … for update ?

Относно вашата актуализация:

да Поради limit 1 , ще намери съвпадение и веднага ще спре. Това, което вероятно се случва обаче, е, че не се оценява where клауза в същия ред в зависимост от вашите заявки. SQL не предлага гаранция, че a <> 0 част в a <> 0 and b / a > c първо се оценява. Приложено към вашия случай, то не предлага гаранция, че препоръчителното заключване е получено след редът от a се свързва с 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. Deepdive инсталация, PostgreSQL грешка

  2. Функцията PostgreSQL не съществува

  3. Как да репликирате оператори INSERT/UPDATE/DELETE с помощта на JPA и Hibernate

  4. Съставна OR SQL заявка (заявка #1 с WITH) и (заявка #2) с COUNT() извинения

  5. POSTGRESQL INSERT, ако конкретно име на ред не съществува?