Det kan vara användbart att titta på hur denna fråga faktiskt exekveras av MySQL:
select * from tbl_codes where available = 1 order by rand() limit 1 for update
Detta kommer att läsa och sortera alla rader som matchar WHERE villkor, generera ett slumptal med rand() i en virtuell kolumn för varje rad, sortera alla rader (i en temporär tabell) baserat på den virtuella kolumnen och returnera sedan rader till klienten från den sorterade uppsättningen tills LIMIT nås (i detta fall bara en). FOR UPDATE påverkar låsning som görs av hela satsen medan den körs, och som sådan tillämpas satsen när rader läses inom InnoDB , inte när de returneras till klienten.
Bortsett från de uppenbara prestandakonsekvenserna av ovanstående (det är fruktansvärt), kommer du aldrig att få rimligt låsbeteende av det.
Kort svar:
- Välj den rad du vill använda med
RAND()eller någon annan strategi du gillar, för att hitta denPRIMARY KEYvärdet på den raden. T.ex.:SELECT id FROM tbl_codes WHERE available = 1 ORDER BY rand() LIMIT 1 - Lås raden du vill använda med dess
PRIMARY KEYendast. T.ex.:SELECT * FROM tbl_codes WHERE id = N
Förhoppningsvis hjälper det.