sql >> Databáze >  >> RDS >> PostgreSQL

Poradní zámky nebo NOWAIT, abyste se vyhnuli čekání na zamčené řádky?

FOR UPDATE NOWAIT je dobrý nápad pouze tehdy, pokud trváte na uzamčení konkrétního řádku, což není co potřebuješ. Chcete jen jakékoli kvalifikační, dostupný (odemčený) řádek. Důležitý rozdíl je tento (cituji manuál pro Postgres 9.4):

Pomocí NOWAIT , příkaz namísto čekání hlásí chybu, pokud nelze vybraný řádek okamžitě uzamknout.

Identické dotazy se velmi pravděpodobně pokusí uzamknout stejný libovolný výběr. FOR UPDATE NOWAIT jen se zachrání s výjimkou (která vrátí celou transakci zpět, pokud chybu nezachytíte) a musíte to zkusit znovu.

Řešení v mé odkazované odpovědi na dba.SE používá kombinaci obyčejného FOR UPDATE v kombinaci s pg_try_advisory_lock() :

pg_try_advisory_lock je podobný pg_advisory_lock , kromě toho, že funkce nebude čekat, až bude zámek dostupný. Buď okamžitě získá zámek a vrátí hodnotu true, nebo vrátí hodnotu false, pokud zámek nelze získat okamžitě.

Takže vaše nejlepší možnost je ... třetí alternativa:nový FOR UPDATE SKIP LOCKED v Postgres 9.5, který implementuje stejné chování bez dalšího volání funkce.

Manuál pro Postgres 9.5 porovnává tyto dvě možnosti a ještě více vysvětluje rozdíl:

Chcete-li zabránit tomu, aby operace čekala na potvrzení jiných transakcí, použijte buď NOWAIT nebo SKIP LOCKED volba. Pomocí NOWAIT Pokud nelze vybraný řádek okamžitě uzamknout, příkaz namísto čekání hlásí chybu. S SKIP LOCKED , všechny vybrané řádky, které nelze okamžitě uzamknout, jsou přeskočeny.

Na Postgres 9.4 nebo starší vaše další nejlepší možnost je použít pg_try_advisory_xact_lock(id) v kombinaci s FOR UPDATE jak je ukázáno v odkazované odpovědi:

  • AKTUALIZACE Postgresu … LIMIT 1

(Také s implementací s FOR UPDATE SKIP LOCKED .)

Stranou

Přísně vzato dostanete svévolné, ne skutečně náhodné výběry. To může být důležitý rozdíl.
Auditovaná verze vašeho dotazu je v mé odpovědi na vaši další otázku.




  1. node-mysql více příkazů v jednom dotazu

  2. Vložte Python Dictionary pomocí Psycopg2

  3. Vytvořte kontingenční zobrazení v SQL z tabulky SQL

  4. SQLAlchemy, Psycopg2 a Postgresql COPY