sql >> Base de Datos >  >> RDS >> Mysql

Bloqueo inesperado de la tabla con clave principal y clave única

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.