Tema SQL
FOR UPDATE, SKIP LOCKED y NOWAIT
Bloquear filas leídas para transacciones concurrentes o fallar rápido si hay bloqueo.
Descripción
SELECT … FOR UPDATE bloquea las filas seleccionadas hasta COMMIT/ROLLBACK (según motor y nivel de aislamiento). FOR UPDATE SKIP LOCKED omite filas ya bloqueadas (colas de trabajo). NOWAIT lanza error si no puede bloquear al instante. Sintaxis y soporte varían (PostgreSQL, Oracle, MySQL InnoDB…).
Estructura general
Forma habitual de la sentencia: orden de cláusulas, qué parte filtra, agrupa o proyecta columnas, y qué devuelve el motor. Cópiala como plantilla y sustituye nombres por tus tablas reales.
SELECT * FROM trabajos
WHERE estado = 'pendiente'
ORDER BY creado_en
LIMIT 1
FOR UPDATE SKIP LOCKED;
SELECT * FROM cuentas WHERE id = 1 FOR UPDATE NOWAIT;
Componentes
Cada componente tiene un papel concreto en la ejecución lógica de la sentencia. Léelos en orden: así entiendes qué puedes omitir, qué es obligatorio y qué expresiones son válidas en cada sitio según tu motor.
- FOR UPDATE
- Evita que otra transacción modifique esas filas hasta liberar.
- SKIP LOCKED
- Patrón cola: varios workers toman distintas filas sin esperarse.
- NOWAIT
- Útil para evitar deadlocks o largas esperas; manejar excepción en aplicación.
Ejemplos
Ejemplo 1
BEGIN;
SELECT id FROM tareas
WHERE asignado_a IS NULL
ORDER BY prioridad DESC
LIMIT 5
FOR UPDATE SKIP LOCKED;
-- actualizar filas tomadas…
COMMIT;
Ejemplo 2
SELECT id FROM pedidos WHERE id = 1 FOR SHARE; -- PostgreSQL
Los ejemplos son ilustrativos. En producción usa consultas parametrizadas (prepared statements), revisa índices y aplica el principio de menor privilegio en cuentas de base de datos.