использовать MySQL выбрать несуществующую строку для обновления возвращает тупик? - PullRequest
0 голосов
/ 04 августа 2020

Структура таблицы

CREATE TABLE `tableA` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '',
  `name` varchar(32) NOT NULL '',
  PRIMARY KEY (`id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

Два потока работают так (нет идентификатора записи, равного 1001)

begin;
select * from tableA where id = 1001 for update;
insert into tableA select 1001, 'nameA';
commit;
  • И threadA, и threadB выберите ... для обновления успешное выполнение
  • ThreadB получит взаимоблокировку при попытке вставить перед ThreadA зафиксировать ;

Я знаю MySQL поддержка Блокировка следующей клавиши и Блокировка зазора , чтобы заблокировать индекс, но почему и потокA, и потокB могут успешно заблокировать индекс?

более того, как возникает эта взаимоблокировка?

update для получения дополнительной информации

в этом примере ниже threadB будет ждать, пока threadA не зафиксирует, если threadA select ... для обновления выполнено успешно, хотя нет идентификатор записи равен 1001.

threadA

begin;
select * from tableA where id = 1001 for update;
insert into tableA select 1001, 'nameA';
commit;

threadB

insert into tableA select 1001, 'nameA';

Так что я уверен, хотя 1001 не существует, но с select ... для обновления MySQL по-прежнему блокирует индекс, чтобы другие не вставляли 1001, но блокировка двух потоков, индекс с тем же диапазоном не имеет конфликта, что меня сильно смущает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...