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;
Isso parece funcionar em Read Committed. É apenas sql (igual ao seu código) e pode ser executado em uma chamada (mais rápido).
@Seth Robertson:Não é seguro sem LOCK TABLE e sem loop while.
Se houver transação A e transação B ao mesmo tempo:A selecionará a primeira linha e B selecionará a primeira linha. A bloqueará e atualizará a linha, B terá que esperar até que A confirme. Então B irá verificar novamente a condição job_name IS NULL. É falso e B não atualizará - B não selecionará a próxima linha, mas apenas verificará novamente e retornará um resultado vazio.
@joegester:SELECT FOR UPDATE não é o problema porque todas as tabelas estão bloqueadas.
Talvez haja outra maneira de fazer o trabalho - se você excluir e inserir linhas (em outra tabela?) em vez de definir NULL. Mas não tenho certeza de como.