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;
Dette ser ud til at virke i Read Committed. Det er kun sql (samme som din kode) og kan udføres i ét opkald (hurtigere).
@Seth Robertson:Det er ikke sikkert uden LOCK TABLE og uden while-løkke.
Hvis der er transaktion A og transaktion B på samme tid:A vil vælge første række og B vil vælge første række. A vil låse og opdatere række, B skal vente til A commit. Så kontrollerer B igen betingelse jobnavn ER NULL. Det er falsk, og B vil ikke opdatere - B vil ikke vælge næste række, men vil kun kontrollere igen og returnere et tomt resultat.
@joegester:SELECT FOR UPDATE er ikke problemet, fordi alle tabeller er låst.
Måske er der en anden måde at udføre jobbet på - hvis du sletter og indsætter rækker (i en anden tabel?) i stedet for at sætte NULL. Men jeg er ikke sikker på hvordan.