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;
Ini tampaknya berfungsi di Baca Berkomitmen. Ini hanya sql (sama dengan kode Anda) dan dapat dieksekusi dalam satu panggilan (lebih cepat).
@Seth Robertson:Tidak aman tanpa LOCK TABLE dan tanpa loop while.
Jika ada transaksi A dan transaksi B secara bersamaan:A akan memilih baris pertama dan B akan memilih baris pertama. A akan mengunci dan memperbarui baris, B harus menunggu hingga A melakukan. Kemudian B akan mengecek kembali kondisi job_name IS NULL. Itu salah dan B tidak akan memperbarui - B tidak akan memilih baris berikutnya tetapi hanya akan memeriksa ulang dan mengembalikan hasil yang kosong.
@joegester:SELECT FOR UPDATE tidak masalah karena semua tabel terkunci.
Mungkin ada cara lain untuk melakukan pekerjaan - jika Anda menghapus dan menyisipkan baris (di tabel lain?) Alih-alih mengatur NULL. Tapi saya tidak yakin bagaimana caranya.