Může být užitečné podívat se, jak tento dotaz ve skutečnosti provádí MySQL:
select * from tbl_codes where available = 1 order by rand() limit 1 for update
To přečte a seřadí všechny řádky, které odpovídají WHERE podmínku, vygenerujte náhodné číslo pomocí rand() do virtuálního sloupce pro každý řádek, seřaďte všechny řádky (v dočasné tabulce) na základě tohoto virtuálního sloupce a poté vraťte řádky klientovi z seřazené sady až do LIMIT je dosaženo (v tomto případě pouze jeden). FOR UPDATE ovlivňuje zamykání provedené celým příkazem během jeho provádění a jako taková se klauzule použije při čtení řádků v rámci InnoDB , ne jak jsou vráceny klientovi.
Když pomineme zjevné důsledky výše uvedeného na výkon (je to hrozné), nikdy z toho nedostanete rozumné chování při zamykání.
Krátká odpověď:
- Vyberte požadovaný řádek pomocí
RAND()nebo jakoukoli jinou strategii, kterou chcete, abyste našliPRIMARY KEYhodnotu toho řádku. Např.:SELECT id FROM tbl_codes WHERE available = 1 ORDER BY rand() LIMIT 1 - Zamkněte požadovaný řádek pomocí jeho
PRIMARY KEYpouze. Např.:SELECT * FROM tbl_codes WHERE id = N
Snad to pomůže.