sql >> Databasteknik >  >> RDS >> Mysql

MySQL:Hur man uppnår transaktionslåsning på radnivå istället för tabelllåsning

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:

  1. Välj den rad du vill använda med RAND() eller någon annan strategi du gillar, för att hitta den PRIMARY KEY värdet på den raden. T.ex.:SELECT id FROM tbl_codes WHERE available = 1 ORDER BY rand() LIMIT 1
  2. Lås raden du vill använda med dess PRIMARY KEY endast. T.ex.:SELECT * FROM tbl_codes WHERE id = N

Förhoppningsvis hjälper det.



  1. MySQL-konverteringsfunktion

  2. SQLPlus - spoolning till flera filer från PL/SQL-block

  3. Oracle - Varför ska jag använda paket istället för fristående procedurer eller funktioner

  4. MySQL:hur skulle jag gå tillväga för att visa enkla kategorier för detta?