solo es una buena idea si insiste en bloquear una fila en particular, lo cual no Que necesitas. Solo quieres cualquiera Fila clasificatoria disponible (desbloqueada). La diferencia importante es esta (citando el manual de Postgres 9.4):FOR UPDATE NOWAIT
Con NOWAIT
, la declaración informa un error, en lugar de esperar, si una fila seleccionada no se puede bloquear de inmediato.
Es muy probable que las consultas idénticas intenten bloquear la misma selección arbitraria. FOR UPDATE NOWAIT
simplemente se rescatará con una excepción (que revertirá toda la transacción a menos que atrape el error) y tendrá que volver a intentarlo.
La solución en mi respuesta referenciada en dba.SE usa una combinación de FOR UPDATE
simple en combinación con pg_try_advisory_lock()
:
pg_try_advisory_lock
es similar a pg_advisory_lock
, excepto que la función no esperará a que el bloqueo esté disponible. Obtendrá el bloqueo inmediatamente y devolverá verdadero, o devolverá falso si el bloqueo no se puede adquirir de inmediato.
Así que tu mejor opción es... la tercera alternativa:el nuevo FOR UPDATE SKIP LOCKED
en Postgres 9.5, que implementa el mismo comportamiento sin llamada de función adicional.
El manual de Postgres 9.5 compara las dos opciones y explica la diferencia un poco más:
Para evitar que la operación espere a que se confirmen otras transacciones, utilice la función NOWAIT
o SKIP LOCKED
opción. Con NOWAIT
, la declaración informa de un error, en lugar de esperar, si una fila seleccionada no se puede bloquear inmediatamente. Con SKIP LOCKED
, se omitirán las filas seleccionadas que no se puedan bloquear inmediatamente.
En Postgres 9.4 o anterior, su próxima mejor opción es usar pg_try_advisory_xact_lock(id)
en combinación con FOR UPDATE
como se demuestra en la respuesta a la que se hace referencia:
- ACTUALIZACIÓN de Postgres... LÍMITE 1
(También con una implementación con FOR UPDATE SKIP LOCKED
.)
Estrictamente hablando, obtienes selecciones arbitrarias, no verdaderamente aleatorias. Esa puede ser una distinción importante.
Una versión auditada de su consulta se encuentra en mi respuesta a su otra pregunta.