sql >> Database teknologi >  >> RDS >> Mysql

Uventet låsning til bord med primær nøgle og unik nøgle

Det problem, du oplever, opstår, fordi MySQL ikke bare låser tabelrækken for en værdi, du vil indsætte, den låser alle mulige værdier mellem det forrige id og det næste id i rækkefølge, så genbrug dit eksempel nedenfor:

DROP TABLE IF EXISTS foo;
CREATE TABLE `foo` (
  `i` INT(11) NOT NULL,
  `j` INT(11) DEFAULT NULL,
  PRIMARY KEY (`i`),
  UNIQUE KEY `jk` (`j`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ;
INSERT INTO foo VALUES (5,5), (8,8), (11,11);

Antag, at du starter med transaktion TX1:

START TRANSACTION;
REPLACE INTO foo VALUES(8,8);

Så hvis du starter en transaktion TX2 , uanset INSERT eller REPLACE ved hjælp af et id mellem 5 og 11 vil være låst:

START TRANSACTION;
REPLACE INTO foo VALUES(11,11);

Det ser ud til, at MySQL bruger denne form for låsning for at undgå "fantomproblemet" beskrevet her:http://dev.mysql.com/doc/refman/5.0/en/innodb-next-key-locking.html , MySQL bruger en "next-key locking", der kombinerer indeksrækkelåsning med spaltelåsning, dette betyder for os, at den vil låse en masse mulige id'er mellem forrige og næste id'er, og vil også låse forrige og næste id'er .

For at undgå dette, prøv at oprette en serveralgoritme, der indsætter dine poster, så poster indsat i forskellige transaktioner ikke overlapper, eller i det mindste ikke udfører alle dine transaktioner på samme tid, så TX behøver ikke at vente på hinanden.



  1. Samling af flere poster efter dato

  2. MySQL kamp mod - I BOOLEAN MODE?

  3. UTF-8 hele vejen igennem

  4. Sådan optimerer du SQL-forespørgsel med vinduesfunktioner