MySQL таблица InnoDB заблокирована, но я могу «выбрать» из другого сеанса. Что дает? - PullRequest
1 голос
/ 14 сентября 2011

Во время разработки некоторого кода мне нужно было «блокировать запись» таблицы InnoDB, чтобы избежать проблем параллелизма в условиях гонки.«блокировка чтения» не достаточно хороша, поскольку некоторые параллельные сеансы, которые будут «читать» заблокированную таблицу (заблокированную другим сеансом), получат ложные данные, поскольку то, что она читает, может испариться (удалить), когда сеанс блокировки завершит свою работу.

Насколько мне нужна блокировка записи.Комментарии приветствуются, но просто потребуется много времени, чтобы объяснить, почему (по моему скромному мнению) я не вижу другого способа, кроме полной блокировки терминала в таблице.

Теперь для моих тестов я открыл дваСессии командной строки mysql, как с обычным пользователем (без рута или аналогичных).В одном сеансе я сделал: блокировка таблиц mytable write;в результате все в порядке (очень хорошо, затронуто 0 строк ...) Во втором сеансе командной строки я подключился к той же БД и выполнил простой выбор * в той же таблице.К моему удивлению я получил полный ответ.В других тестах реального веб-приложения я заметил, что в некоторых случаях использования веб-приложения (PHP + PDO с атрибутом постоянных подключений) командная строка или подключение к mysql в сети блокировались до снятия блокировки, но я не идентифицировалчто именно вызвало этот (желательный) эффект, и в нем также задействована другая среда (PHP + PDO, как подробно, и командная строка против 2 сеансов командной строки).

Мой вопрос: почему?почему второй сеанс командной строки, выполняющий простое 'select' для таблицы с блокировкой записи, заблокирован?

Имеет ли это отношение к природе блокировок InnoDB, которая основана на строках?Если да, то как именно это связано?Как сделать Я получил такую ​​простую блокировку, реализованную в таблице InnoDB.Я знаю, что могу создать «семафорную» таблицу MyIsam без какой-либо цели, кроме как действовать как «светофор», но это утратит эффект защиты на уровне БД и переместит всю защиту, которая должна быть сделана (или сделана неправильно) в приложении.уровень.

TIA!

Версия MySQL 5.1.54 (Ubuntu 11.04).

1 Ответ

2 голосов
/ 14 сентября 2011

Хотя InnoDB имеет блокировку на уровне строк, он также имеет многоверсионное управление параллелизмом http://en.wikipedia.org/wiki/Multiversion_concurrency_control,, так что это означает, что читатели не должны блокироваться средствами записи.Они могут просто увидеть текущую версию записи.(Техническая реализация, при обновлении строка изменяется на месте, а предыдущая редакция будет записана для отмены места для более старых транзакций.)

Если вы хотите сделать блокировку чтения блоков записи, вам нужно изменить SELECTбыть ДЛЯ ОБНОВЛЕНИЯ (т.е. ВЫБРАТЬ * ОТ my_table WHERE cola = n ДЛЯ ОБНОВЛЕНИЯ).

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