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.