Можно ли реализовать пессимистическую блокировку, используя mysql и innodb? - PullRequest
1 голос
/ 03 июля 2019

Поток для блокировки, который у меня есть в настоящее время, равен SELECT ... FOR UPDATE, за которым следует INSERT. например,

BEGIN;
SELECT count(*) FROM test WHERE col = 1 FOR UPDATE;
# check to ensure an invariant will still be met after the insert.
INSERT INTO test (col) VALUES (1);
COMMIT;

Я ожидал, что SELECT выше получит эксклюзивную блокировку чего-либо, чтобы предотвратить одновременное нахождение нескольких вызывающих абонентов в критическом разделе, но похоже, что по умолчанию InnoDB получает только общую блокировку для таблицы или пробела индекса , Если две одновременные транзакции пытаются сделать это одновременно, они оба могут получить общую блокировку, но одна из них завершится с ошибкой взаимоблокировки при попытке вставить.

Есть ли способ заставить этот код вести себя как стандартная пессимистическая блокировка для предотвращения одновременного чтения?

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

...