sql >> Database >  >> RDS >> Mysql

MySQL:Transactievergrendeling op rijniveau bereiken in plaats van tabelvergrendeling

Het kan handig zijn om te kijken hoe deze query daadwerkelijk wordt uitgevoerd door MySQL:

select * from tbl_codes where available = 1 order by rand() limit 1 for update

Hiermee worden alle rijen gelezen en gesorteerd die overeenkomen met de WHERE voorwaarde, genereer een willekeurig getal met rand() in een virtuele kolom voor elke rij, sorteer alle rijen (in een tijdelijke tabel) op basis van die virtuele kolom en retourneer vervolgens rijen naar de client van de gesorteerde set tot de LIMIT is bereikt (in dit geval slechts één). De FOR UPDATE heeft invloed op de vergrendeling die wordt gedaan door de hele instructie terwijl deze wordt uitgevoerd, en als zodanig wordt de clausule toegepast terwijl rijen worden gelezen binnen InnoDB , niet als ze worden teruggestuurd naar de klant.

Afgezien van de voor de hand liggende prestatie-implicaties van het bovenstaande (het is verschrikkelijk), zul je er nooit redelijk vergrendelingsgedrag van krijgen.

Kort antwoord:

  1. Selecteer de gewenste rij met RAND() of een andere strategie die je leuk vindt, om de PRIMARY KEY . te vinden waarde van die rij. Bijvoorbeeld:SELECT id FROM tbl_codes WHERE available = 1 ORDER BY rand() LIMIT 1
  2. Vergrendel de gewenste rij met de PRIMARY KEY enkel en alleen. Bijv.:SELECT * FROM tbl_codes WHERE id = N

Hopelijk helpt dat.



  1. MySQL Workbench - Forward Engineering - Fout 1005:Kan tabel niet maken (fout:150)

  2. SQL-script om ALLE buitenlandse sleutels te wijzigen om toe te voegen ON DELETE CASCADE

  3. ASP.NET gebruik SqlConnection connect MySQL

  4. VERWIJDEREN UIT ... rapportage syntaxisfout op of nabij .