n'est une bonne idée que si vous insistez pour verrouiller une ligne particulière, ce qui n'est pas De quoi as-tu besoin. Vous voulez juste tout qualification, ligne disponible (déverrouillée). La différence importante est la suivante (en citant le manuel de Postgres 9.4) :FOR UPDATE NOWAIT
Avec
NOWAIT
, l'instruction signale une erreur, plutôt que d'attendre, si une ligne sélectionnée ne peut pas être verrouillée immédiatement.
Des requêtes identiques essaieront très probablement de verrouiller le même choix arbitraire. FOR UPDATE NOWAIT
va simplement renflouer avec une exception (qui annulera toute la transaction à moins que vous n'interceptiez l'erreur) et vous devez réessayer.
La solution dans ma réponse référencée sur dba.SE utilise une combinaison de FOR UPDATE
en combinaison avec pg_try_advisory_lock()
:
pg_try_advisory_lock
est similaire àpg_advisory_lock
, sauf que la fonction n'attendra pas que le verrou soit disponible. Il obtiendra soit le verrou immédiatement et renverra vrai, ou renverra faux si le verrou ne peut pas être acquis immédiatement.
Donc, votre meilleure option est ... la troisième alternative :le nouveau FOR UPDATE SKIP LOCKED
dans Postgres 9.5, qui implémente le même comportement sans appel de fonction supplémentaire.
Le manuel de Postgres 9.5 compare les deux options, expliquant davantage la différence :
Pour empêcher l'opération d'attendre que d'autres transactions soient validées, utilisez soit le
NOWAIT
ouSKIP LOCKED
option. AvecNOWAIT
, l'instruction signale une erreur, plutôt que d'attendre, si une ligne sélectionnée ne peut pas être verrouillée immédiatement. AvecSKIP LOCKED
, toutes les lignes sélectionnées qui ne peuvent pas être verrouillées immédiatement sont ignorées.
Sur Postgres 9.4 ou une version antérieure, votre prochaine meilleure option est d'utiliser pg_try_advisory_xact_lock(id)
en combinaison avec FOR UPDATE
comme démontré dans la réponse référencée :
- MISE À JOUR Postgres… LIMITER 1
(Aussi avec une implémentation avec FOR UPDATE SKIP LOCKED
.)
À proprement parler, vous obtenez des choix arbitraires, pas vraiment aléatoires. Cela peut être une distinction importante.
Une version vérifiée de votre requête se trouve dans ma réponse à votre autre question.