Saya punya solusi praktis untuk Anda, yang pernah saya lihat diimplementasikan dalam sebuah proyek di tempat kerja saya. Daripada hanya menggunakan 0 dan 1 untuk yang tidak lengkap dan selesai, perluas set Anda untuk menyertakan lebih banyak kasus.
Sebut saja kolom itu status . Berikut adalah nilai yang berbeda dari kolom tersebut dan status pekerjaan yang sesuai.
- Saat status 0, pekerjaan belum diambil oleh utas pekerja mana pun.
- Saat status 1, pekerjaan telah diambil oleh thread pekerja dan sedang dalam proses.
- Bila statusnya 2, pekerjaan telah gagal. (Anda harus mempertimbangkan kemungkinan kegagalan dalam pemrosesan.)
- Saat status 3, pekerjaan telah selesai.
Utas Anda harus berisi logika sehingga hanya mengambil pekerjaan dengan status 0 dan mengubah status menjadi 1. Ini akan melarang utas lain untuk mengambil pekerjaan yang sedang diproses. Ketika pekerjaan selesai, statusnya diatur ke 3 dan jika pekerjaan gagal, statusnya diatur ke 2. Kemudian utas dapat melanjutkan dan mencari pekerjaan lain yang masih harus diselesaikan.
Anda juga dapat meminta utas untuk mempertimbangkan mengambil tugas dengan status 2, tetapi Anda harus mendefinisikan logika untuk menentukan jumlah percobaan ulang yang terbatas.
EDIT:
Setelah diskusi panjang , kami menemukan solusi bersama. Jawaban saya di atas bagus dalam keadaan yang lebih umum ketika 'pekerjaan' adalah proses yang membutuhkan waktu untuk diselesaikan. Tapi itu tidak terjadi dalam masalah OP.
Jadi solusi yang akhirnya berhasil adalah ini:
BEGIN
SELECT * FROM Jobs WHERE JobID = (SELECT * FROM Jobs WHERE completed = 0 LIMIT 1) LOCK IN SHARE MODE;
UPDATE Jobs SET completed = 1 WHERE JobID = (PREVIOUS ID);
COMMIT;