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

Съветни заключване или NOWAIT, за да избегнете чакането на заключени редове?

FOR UPDATE NOWAIT е добра идея само ако настоявате да заключите конкретен ред, което е не от какво имаш нужда. Просто искате всякакво квалифициращ, наличен (отключен) ред. Важната разлика е следната (цитирайки ръководството за Postgres 9.4):

С NOWAIT , операторът отчита грешка, вместо да чака, ако избран ред не може да бъде заключен незабавно.

Идентични заявки много вероятно ще се опитат да заключат един и същ произволен избор. FOR UPDATE NOWAIT просто ще се спаси с изключение (което ще върне обратно цялата транзакция, освен ако не хванете грешката) и трябва да опитате отново.

Решението в моя препратен отговор на dba.SE използва комбинация от обикновен FOR UPDATE в комбинация с pg_try_advisory_lock() :

pg_try_advisory_lock е подобен на pg_advisory_lock , освен че функцията няма да чака заключването да стане достъпно. Той или ще получи заключването незабавно и ще върне true, или ще върне false, ако заключването не може да бъде получено незабавно.

Така че вашият най-добрият вариант е ... третата алтернатива:новата FOR UPDATE SKIP LOCKED в Postgres 9.5, който реализира същото поведение без допълнително извикване на функция.

Ръководството за Postgres 9.5 сравнява двете опции, обяснявайки още малко разликата:

За да предотвратите операцията да чака други транзакции за извършване, използвайте или NOWAIT или SKIP LOCKED опция. С NOWAIT , операторът отчита грешка, вместо да чака, ако избран ред не може да бъде заключен незабавно. С SKIP LOCKED , всички избрани редове, които не могат да бъдат незабавно заключени, се пропускат.

На Postgres 9.4 или по-стара следващата ви най-добра опция е да използвате pg_try_advisory_xact_lock(id) в комбинация с FOR UPDATE както е показано в посочения отговор:

  • Актуализиране на Postgres… ОГРАНИЧЕНИЕ 1

(Също така с реализация с FOR UPDATE SKIP LOCKED .)

Настрана

Строго погледнато, получавате произволни, а не наистина произволни избори. Това може да е важно разграничение.
Проверена версия на вашата заявка е в моя отговор на другия ви въпрос.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Най-добрите нови функции в PostgreSQL 14

  2. Изберете (извлечете) всички записи от множество схеми с помощта на Postgres

  3. Споделете връзка с postgres db между процеси в Python

  4. SQL подзаявки в ограничение за проверка

  5. Връщане на редове от INSERT с ON CONFLICT без необходимост от актуализиране