Dari sudut pandang teoretis murni, sepertinya Anda tidak mengunci baris yang benar (kondisi berbeda di pernyataan pertama daripada di pernyataan pembaruan; selain itu Anda hanya mengunci satu baris karena LIMIT 1
, sedangkan Anda mungkin memperbarui lebih banyak baris nanti).
Coba ini:
START TRANSACTION;
SELECT v_id FROM v_ext WHERE username IS NULL AND v_id=yyy FOR UPDATE;
UPDATE v_ext SET username=xxx WHERE v_id=yyy;
COMMIT;
[sunting]
Adapun alasan kebuntuan Anda, ini adalah kemungkinan jawaban (dari manual ):
Tanpa indeks, SELECT ... FOR UPDATE
pernyataan cenderung mengunci seluruh tabel, sedangkan dengan indeks, hanya mengunci beberapa baris. Karena Anda tidak mengunci baris kanan di pernyataan pertama, kunci tambahan diperoleh selama pernyataan kedua.
Jelas, kebuntuan tidak dapat terjadi jika seluruh tabel terkunci (yaitu tanpa indeks). Kebuntuan pasti dapat terjadi pada penyiapan kedua.