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;
Detta verkar fungera i Read Committed. Det är bara sql (samma som din kod) och kan köras i ett anrop (snabbare).
@Seth Robertson:Det är inte säkert utan LOCK TABLE och utan while-loop.
Om det finns transaktion A och transaktion B samtidigt:A väljer första raden och B väljer första raden. A kommer att låsa och uppdatera rad, B måste vänta tills A commit. Då kommer B att kontrollera villkoret jobbnamn ÄR NULL igen. Det är falskt och B kommer inte att uppdatera - B kommer inte att välja nästa rad utan kommer bara att kontrollera igen och returnera tomt resultat.
@joegester:VÄLJ FÖR UPPDATERING är inte problemet eftersom alla tabeller är låsta.
Kanske finns det ett annat sätt att göra jobbet - om du tar bort och infogar rader (i en annan tabell?) istället ställer du in NULL. Men jag är inte säker på hur.