sql >> Base de Datos >  >> RDS >> PostgreSQL

¿Bloqueos de aviso o NOWAIT para evitar esperar filas bloqueadas?

FOR UPDATE NOWAIT 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):

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 .)

Aparte

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.