Или нет

0
CREATE TABLE 'z' (
  'a' int(11) NOT NULL,
  'b' int(11) DEFAULT NULL,
  PRIMARY KEY ('a'),
  KEY 'b' ('b')
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO 'test'.'z' ('a', 'b') VALUES (1, 1);
INSERT INTO 'test'.'z' ('a', 'b') VALUES (3, 1);
INSERT INTO 'test'.'z' ('a', 'b') VALUES (5, 3);
INSERT INTO 'test'.'z' ('a', 'b') VALUES (7, 6);
INSERT INTO 'test'.'z' ('a', 'b') VALUES (10, 8);
INSERT INTO 'test'.'z' ('a', 'b') VALUES (20, 30);
INSERT INTO 'test'.'z' ('a', 'b') VALUES (50, 60);
INSERT INTO 'test'.'z' ('a', 'b') VALUES (45, 90);
INSERT INTO 'test'.'z' ('a', 'b') VALUES (2, 99);

transaction_isolation = REPEATABLE-READ
tx_isolation = REPEATABLE-READ

СЕССИЯ 1

начать;

выберите * from z, где b = 60 для обновления;

СЕССИЯ 2

начать;

вставить в z выбрать 4, 90; /* почему это невозможно вставить? */

ERROR 1205 (HY000): превышено время ожидания блокировки; попробуйте перезапустить транзакцию

вставить в z выбрать 46, 90; /* Но это можно вставить? */

Запрос ОК, 1 строка затронута (0.00 сек)

Записи: 1 Дубликаты: 0 Предупреждения: 0

Как вышеописанный шаг: можно вставить, но другого не может быть. они имеют одинаковое значение - 90.

Теги:

1 ответ

0

Да, это зазор.

Эти две вставки на самом деле не пытаются вставить одно и то же значение, поскольку вторичные индексы также сохраняют копию первичного ключа в конце (это то, как поиск индекса находит исходную строку, если на столбцы ссылаются больше, чем в индексе).

В индексе b строки, о которых идет речь, будут отсортированы следующим образом.

b   a
60, 50
90, 4
90, 45
90, 46

Из этой иллюстрации видно, что (4,90) принадлежит в промежутке сразу после (60,50), но (46,90) находится не в этом промежутке.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню