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.