is alleen een goed idee als u erop staat een bepaalde rij te vergrendelen, wat niet . is wat je nodig hebt. Je wilt gewoon elke kwalificerende, beschikbare (ontgrendelde) rij. Het belangrijke verschil is dit (met verwijzing naar de handleiding voor Postgres 9.4):FOR UPDATE NOWAIT
Met
NOWAIT
, meldt de instructie een fout, in plaats van te wachten, als een geselecteerde rij niet onmiddellijk kan worden vergrendeld.
Identieke zoekopdrachten zullen zeer waarschijnlijk dezelfde willekeurige keuze proberen te vergrendelen. FOR UPDATE NOWAIT
zal gewoon redden met een uitzondering (die de hele transactie terugdraait, tenzij je de fout opvangt) en je moet het opnieuw proberen.
De oplossing in mijn antwoord waarnaar wordt verwezen op dba.SE gebruikt een combinatie van gewoon FOR UPDATE
in combinatie met pg_try_advisory_lock()
:
pg_try_advisory_lock
lijkt oppg_advisory_lock
, behalve dat de functie niet wacht tot het slot beschikbaar is. Het zal het slot onmiddellijk verkrijgen en true retourneren, of false retourneren als het slot niet onmiddellijk kan worden verkregen.
Dus je beste optie is ... het derde alternatief:de nieuwe FOR UPDATE SKIP LOCKED
in Postgres 9.5, dat hetzelfde gedrag implementeert zonder extra functieaanroep.
De handleiding voor Postgres 9.5 vergelijkt de twee opties en legt het verschil wat meer uit:
Om te voorkomen dat de bewerking wacht tot andere transacties worden uitgevoerd, gebruikt u de
NOWAIT
ofSKIP LOCKED
optie. MetNOWAIT
, rapporteert de instructie een fout in plaats van te wachten als een geselecteerde rij niet onmiddellijk kan worden vergrendeld. MetSKIP LOCKED
, worden alle geselecteerde rijen die niet onmiddellijk kunnen worden vergrendeld, overgeslagen.
Op Postgres 9.4 of ouder uw volgende beste optie is om pg_try_advisory_xact_lock(id)
. te gebruiken in combinatie met FOR UPDATE
zoals aangetoond in het antwoord waarnaar wordt verwezen:
- Postgres-UPDATE ... LIMIET 1
(Ook met een implementatie met FOR UPDATE SKIP LOCKED
.)
Strikt genomen krijg je willekeurige, niet echt willekeurige keuzes. Dat kan een belangrijk onderscheid zijn.
Een gecontroleerde versie van uw vraag staat in mijn antwoord op uw andere vraag.