Я столкнулся с проблемой блокировки innodb для транзакций в таблице с первичным ключом и отдельным уникальным индексом. Кажется, что если TX удаляет запись с использованием уникального ключа, а затем повторно вставляет ту же запись, это приведет к блокировке следующего ключа вместо ожидаемой блокировки записи (поскольку ключ уникален). См. Ниже тестовый пример, а также разбивку того, какие записи я ожидаю иметь какие блокировки:
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);
(Примечание: просто запустите sql TX2 после sql TX1 в отдельном соединении)
START TRANSACTION;
DELETE FROM foo WHERE i=8;
приведет к исключительная блокировка для i = 8 (без блокировки, поскольку i является первичным ключом и уникальным)
INSERT INTO foo VALUES(8,8);
приводит к исключительной блокировке для i = 8 и j = 8, и общая блокировка намерения на i = 6 & i = 7, а также j = 6 & j = 7
START TRANSACTION;
INSERT INTO foo VALUES(7,7);
приводит к исключительной блокировке для i = 7 & j = 7, а также к общей блокировке намерения на on i = 6 & j = 6
Я ожидал, что TX2 не будет заблокирован TX1, но это так. Как ни странно, похоже, что блокировка связана со вставкой через TX1. Я говорю это потому, что если оператор вставки TX1 не запускается после удаления, вставка TX2 не блокируется. Это похоже на то, как если бы повторная вставка (8,8) в TX1 вызывала блокировку следующего ключа в индексе j для (6,8].
Любое понимание будет очень признательно.