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;
Dies scheint in Read Committed zu funktionieren. Es ist nur SQL (dasselbe wie Ihr Code) und kann in einem Aufruf ausgeführt werden (schneller).
@Seth Robertson:Ohne LOCK TABLE und ohne While-Schleife ist es nicht sicher.
Wenn Transaktion A und Transaktion B gleichzeitig vorhanden sind:A wählt die erste Zeile aus und B wählt die erste Zeile aus. A sperrt und aktualisiert die Zeile, B muss warten, bis A festschreibt. Dann überprüft B erneut die Bedingung job_name IS NULL. Es ist falsch und B wird nicht aktualisiert - B wählt nicht die nächste Zeile aus, sondern prüft nur erneut und gibt ein leeres Ergebnis zurück.
@joegester:SELECT FOR UPDATE ist nicht das Problem, da alle Tabellen gesperrt sind.
Vielleicht gibt es eine andere Möglichkeit, die Arbeit zu erledigen - wenn Sie Zeilen löschen und einfügen (in einer anderen Tabelle?), Setzen Sie stattdessen NULL. Aber ich bin mir nicht sicher wie.