Неожиданная блокировка для таблицы с первичным и уникальным ключами

Я столкнулся с проблемой блокировки 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 в отдельном соединении)

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

TX2

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].

Любое понимание будет очень признательно.

9
задан Jake McGraw 31 January 2011 в 15:50
поделиться