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

Consistencia en postgresql con bloqueo y selección para actualizar

BEGIN; 
LOCK TABLE slots IN ACCESS EXCLUSIVE MODE; 
UPDATE slots SET job_name = '111' WHERE id IN (SELECT id FROM slots WHERE job_name IS NULL LIMIT 1) RETURNING *;
COMMIT;

Esto parece funcionar en Read Committed. Es solo sql (igual que su código) y se puede ejecutar en una llamada (más rápido).

@Seth Robertson:No es seguro sin LOCK TABLE y sin ciclo while.

Si hay una transacción A y una transacción B al mismo tiempo:A seleccionará la primera fila y B seleccionará la primera fila. A bloqueará y actualizará la fila, B tiene que esperar hasta que A se comprometa. Entonces B volverá a verificar la condición job_name IS NULL. Es falso y B no se actualizará; B no seleccionará la siguiente fila, sino que solo volverá a verificar y arrojará un resultado vacío.

@joegester:SELECCIONAR PARA ACTUALIZAR no es el problema porque todas las tablas están bloqueadas.

Tal vez haya otra forma de hacer el trabajo:si elimina e inserta filas (¿en otra tabla?) En lugar de establecer NULL. Pero no estoy seguro de cómo.