El problema que está experimentando ocurre porque MySQL no solo bloquea la fila de la tabla para un valor que va a insertar, sino que bloquea todos los valores posibles entre el id
anterior y la siguiente identificación en orden, entonces, reutilizando su ejemplo a continuación:
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);
Suponga que comienza con la transacción TX1:
START TRANSACTION;
REPLACE INTO foo VALUES(8,8);
Luego, si inicia una transacción TX2
, lo que sea INSERT
o REPLACE
usando un id
entre 5 y 11 estará bloqueado:
START TRANSACTION;
REPLACE INTO foo VALUES(11,11);
Parece que MySQL usa este tipo de bloqueo para evitar el "problema fantasma" descrito aquí:http://dev.mysql.com/doc/refman/5.0/en/innodb-bloqueo-de-tecla-siguiente.html , MySQL utiliza un "bloqueo de clave siguiente", que combina el bloqueo de fila de índice con el bloqueo de espacio, esto significa para nosotros que bloqueará muchas identificaciones posibles entre las identificaciones anterior y siguiente, y también bloqueará las identificaciones anterior y siguiente .
Para evitar esto, intente crear un algoritmo de servidor que inserte sus registros para que los registros insertados en diferentes transacciones no se superpongan, o al menos no ejecute todas sus transacciones al mismo tiempo para que TX
no tiene que esperar el uno al otro.