SELECT… FOR UPDATE для несуществующих строк - PullRequest
0 голосов
/ 03 апреля 2020

меня интересуют блокировки, когда "выберите ... для обновления несуществующих строк"; в настоящее время данные в таблице 'test02' являются такими же:

id

1

3

8

15

20

идентификатор столбца является первичным ключом;

при запуске:

сеанс1: запуск транзакции; выберите * из test02, где id = 7 для обновления;

, затем я открою другой сеанс и запускаюсь как стипендиаты:

сеанс2: начать транзакцию; выберите * из test02, где id = 7 для обновления;

, как я и ожидал, session2 будет ожидать блокировки гэпа (3, 8); однако две сессии проходят нормально. Кто-нибудь может помочь объяснить, почему session2 не ждет?

, но когда я запускаю следующее sql в session3: вставьте в test02 (id) значения (7); сеанс заблокирован, это означает, что в сеансе1 используется блокировка интервала но я не понимаю, почему session2 может работать нормально.

mysql версии 5.7 и 5.8 оба показывают одинаковый результат.

1 Ответ

2 голосов
/ 03 апреля 2020

Из документации MySql (версия 8.0):

Здесь также стоит отметить, что конфликтующие блокировки могут удерживаться в промежутке различными транзакциями. Например, транзакция A может удерживать разделяемую блокировку промежутка (S-lock промежутка) в промежутке, в то время как транзакция B удерживает исключительную блокировку промежутка (X-lock промежутка) в том же промежутке. Причина, по которой допускаются конфликтующие блокировки пробелов, заключается в том, что если запись очищается из индекса, блокировки с пропусками, удерживаемые в записи различными транзакциями, должны быть объединены.

Блокировки пробелов в InnoDB являются «чисто запрещающими», что означает что их единственная цель состоит в том, чтобы предотвратить вставку других транзакций в пробел. Разрывные замки могут сосуществовать. Блокировка промежутка, принятая одной транзакцией, не препятствует тому, чтобы другая транзакция взяла блокировку промежутка в том же самом промежутке. Нет разницы между общими и эксклюзивными блокировками. Они не конфликтуют друг с другом и выполняют одну и ту же функцию.

В вашем примере сеанс 2 не ожидает сеанс 1, потому что именно так работают блокировки пробела в MySQL. Ожидать обратного - значит ожидать поведения, противоречащего документации по продукту.

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