Х-блокировки InnoDB на уровне изоляции READ COMMITTED
Из глоссария MySQL:
ЧИТАТЬ ОБЯЗАТЕЛЬНО
Когда транзакция с этим уровнем изоляции выполняет операции UPDATE ... WHERE или DELETE ... WHERE, другие транзакции могут ждать. Транзакция может выполнять операции SELECT ... FOR UPDATE и LOCK IN SHARE MODE, не заставляя другие транзакции ждать.
Это верно?
UPDATE устанавливает x-блокировки для каждой сканируемой строки, а затем освобождает те блокировки, которые не соответствуют WHERE-части. Оставшиеся строки сохраняют х-блокировки до завершения транзакции. Насколько я знаю, точно так же происходит и с SELECT-FOR UPDATE. Так как же может быть так, что UPDATE может блокировать другие транзакции, а SELECT-FOR UPDATE - нет?
1 ответ
Глоссарий не является точным.
SELECT FOR UPDATE
приобретает X-Lock так же, как UPDATE
делает. В обоих случаях другие транзакции, требующие блокировки любого типа, должны ждать.
SELECT FOR SHARE
(или же LOCK IN SHARE MODE
) приобретает S-замок. Другие транзакции, которым нужны S-блокировки, могут получить их, но другие транзакции, которым нужны X-блокировки, должны ждать.
Уровень изоляции транзакции не имеет ничего общего с необходимыми блокировками, за исключением того, что некоторые типы блокировок пробела не нужны, когда ваша транзакция использует READ-COMMITTED.
Кажется, глоссарий немного забыт. Лучше прочитать https://dev.mysql.com/doc/refman/8.0/en/innodb-locking-reads.html и https://dev.mysql.com/doc/refman/8.0/en/innodb-transaction-isolation-levels.html