При использовании SELECT ... FOR UPDATE
MySQL попытается получить блокировку IX (намеренную исключительную блокировку) для всех строк и связанных записей индекса, которые запрос должен вернуть.Из документации :
Для записей индекса поиск встречает, блокирует строки и любые связанные записи индекса, так же, как если бы вы выполнили инструкцию UPDATE для этих строк.
Одна из ваших двух транзакций сначала выполнит FOR UPDATE
, и в зависимости от того, какая из них удастся выполнить, будет заблокирована вся таблица, поскольку select является SELECT *
без any WHERE
clause.
Более реалистичным сценарием реального мира может быть ситуация, когда одна транзакция блокирует несколько записей для обновления, а другая транзакция одновременно блокирует некоторые другие строки.В этом случае обе транзакции могут выполняться одновременно.Вот пример двух вариантов выбора для обновления, которые не будут блокировать одни и те же записи (при условии, что оба набора результатов не будут пустыми)
SELECT * FROM yourTable WHERE id = 1 FOR UPDATE;
SELECT * FROM yourTable WHERE id = 2 FOR UPDATE;
Если в приведенном выше примере все еще будет отображаться блокировка второй более поздней транзакции, это может бытьпотому что MySQL иногда также может блокировать пробелы после фактических целевых записей.