PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Postgres pg_try_advisory_lock blokuje wszystkie rekordy

Wywołujesz pg_try_advisory_lock() raz na wiersz w całym zestawie, który jest skanowany (w ramach filtrowania, które występuje w where klauzula), podczas gdy chcesz, aby była wywoływana tylko raz na wiersz w tabeli 1 zwróconej przez zapytanie.

Zamiast tego możesz spróbować użyć podzapytania lub 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);

Ale nie należy polegać na tym, aby koniecznie działać zgodnie z oczekiwaniami:Postgres powinien ulec pokusie, aby przepisać go tak, jak początkowe zapytanie.

Inna możliwość jest taka, ponieważ select część instrukcji jest oceniana bardzo późno w zapytaniu:

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;

Prawdziwym problemem w praktyce jest to, że pg_try_advisory_lock() jest czymś, co zwykle można znaleźć w aplikacji lub w funkcji, a nie w zapytaniu, jak to robisz. Skoro o tym mowa, w zależności od tego, co robisz, na pewno nie powinieneś używać select … for update ?

Jeśli chodzi o twoją aktualizację:

TAk. Ze względu na limit 1 , znajdzie dopasowanie i natychmiast się zatrzyma. Prawdopodobnie jednak dzieje się tak, że nie ocenia where klauzula w tej samej kolejności w zależności od zapytań. SQL nie gwarantuje, że a <> 0 część w a <> 0 and b / a > c jest oceniany jako pierwszy. Zastosowany w Twoim przypadku nie gwarantuje, że blokada doradcza zostanie uzyskana po wiersz od a jest połączony z 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. Jak działa Round() w PostgreSQL

  2. Jak słowa kluczowe IMMUTABLE, STABLE i VOLATILE wpływają na zachowanie funkcji?

  3. Nie można znaleźć biblioteki klienta PostgreSQL (libpq)

  4. Jak warunkowo grupować w kolumnę bez użycia FULL OUTER JOIN

  5. Nazwa aplikacji w adresie URL JDBC przy użyciu c3p0