Mungkin berguna untuk melihat bagaimana kueri ini benar-benar dijalankan oleh MySQL:
select * from tbl_codes where available = 1 order by rand() limit 1 for update
Ini akan membaca dan mengurutkan semua baris yang cocok dengan WHERE
kondisi, hasilkan angka acak menggunakan rand()
ke dalam kolom virtual untuk setiap baris, urutkan semua baris (dalam tabel sementara) berdasarkan kolom virtual tersebut, lalu kembalikan baris ke klien dari kumpulan yang diurutkan hingga LIMIT
tercapai (dalam hal ini hanya satu). FOR UPDATE
mempengaruhi penguncian yang dilakukan oleh seluruh pernyataan saat dieksekusi, dan dengan demikian klausa diterapkan saat baris dibaca di dalam InnoDB , tidak saat mereka dikembalikan ke klien.
Mengesampingkan implikasi kinerja yang jelas dari hal di atas (mengerikan), Anda tidak akan pernah mendapatkan perilaku penguncian yang masuk akal darinya.
Jawaban singkat:
- Pilih baris yang Anda inginkan, menggunakan
RAND()
atau strategi lain yang Anda suka, untuk menemukanPRIMARY KEY
nilai baris itu. E.g.:SELECT id FROM tbl_codes WHERE available = 1 ORDER BY rand() LIMIT 1
- Kunci baris yang Anda inginkan menggunakan
PRIMARY KEY
hanya. Misalnya:SELECT * FROM tbl_codes WHERE id = N
Semoga membantu.