Как можно прочитать строку, когда таблица заблокирована для чтения/записи?

Я запускаю эти запросы в MySQL 5.6.13. Я использую повторяемый уровень изоляции чтения. Таблица выглядит следующим образом:

введите здесь описание изображения

В терминале сеанса A я выдал приведенное ниже заявление

UPDATE manufacurer
SET lead_time = 2
WHERE mname = 'Hayleys';

В терминале сеанса B я попытался обновить значение lead_time кабелей ACL до 2. Но поскольку предыдущая команда UPDATE из сеанса A еще не зафиксирована (а сеанс A имеет эксклюзивную блокировку таблицы производителей), это обновление ожидает. Это я могу понять.

Но когда я пытаюсь выполнить оператор SELECT в сеансе B, как показано ниже,

SELECT * FROM manufacturer
WHERE mcode = 'ACL';

он правильно запрашивает таблицу производителей и выдает строку. Как это может произойти? Поскольку сеанс A по-прежнему удерживает монопольную блокировку таблицы производителя, и, как я понимаю, когда монопольная блокировка удерживается на таблице, никакие другие транзакции не могут читать или записывать ее до тех пор, пока предыдущая транзакция не будет зафиксирована.


person Les_Salantes    schedule 12.11.2013    source источник
comment
В заголовке вашего вопроса вы различаете блокировку чтения и записи, а в вопросе вы говорите о блокировке, которая предотвращает чтение и запись. Пожалуйста, обновите свой вопрос / заголовок для согласованности.   -  person Max Leske    schedule 12.11.2013
comment
Поскольку вы не изменяете строку в сеансе B. Данные возвращаются.   -  person Mad Dog Tannen    schedule 12.11.2013
comment
@KayNelson Хм.. Если я правильно понимаю, хотя я не изменяю строку, я все еще пытаюсь читать из нее, и эксклюзивные блокировки не позволяют другим сеансам читать или записывать до тех пор, пока не будет зафиксирована предыдущая транзакция. .   -  person Les_Salantes    schedule 12.11.2013
comment
Вы используете innodb в качестве движка?   -  person Mad Dog Tannen    schedule 12.11.2013
comment
Вы не хотите реализовать такое поведение или задаетесь вопросом, почему это уже происходит? В любом случае обратитесь к блокировке MySQL.   -  person alko    schedule 12.11.2013
comment
@KayNelson Да, я использую innodb в качестве движка   -  person Les_Salantes    schedule 12.11.2013
comment
@alko Мне интересно, почему это происходит   -  person Les_Salantes    schedule 12.11.2013
comment
читать документы; Я обновил вопрос, чтобы отразить ваши комментарии. пожалуйста, проверьте, согласны ли вы с обновлениями   -  person alko    schedule 12.11.2013
comment
@Thili InnoDB обеспечивает блокировку на уровне строк. Ваш UPDATE касается только строки WHERE mname = 'Hayleys'. Ваш SELECT предназначен для данных в другой строке WHERE mcode = 'ACL'. Таким образом, эта строка безопасна для чтения, хотя это также зависит от того, какие индексы у вас есть в вашей таблице — может быть заблокировано больше строк, чем обновленные строки.   -  person nos    schedule 12.11.2013


Ответы (2)


Найдено ниже информации на этой странице

http://dev.mysql.com/doc/refman/5.0/en/set-transaction.html#isolevel_repeatable-read

Характеристики масштаба транзакции

Вы можете установить характеристики транзакции глобально, для текущего сеанса или для следующей транзакции:

С ключевым словом GLOBAL оператор применяется глобально для всех последующих сеансов. Существующие сеансы не затрагиваются.

С ключевым словом SESSION оператор применяется ко всем последующим транзакциям, выполняемым в рамках текущего сеанса.

Без какого-либо ключевого слова SESSION или GLOBAL оператор применяется к следующей (не начатой) транзакции, выполненной в рамках текущего сеанса.

Принято ли это во внимание?

ПОВТОРЯЕМОЕ ЧТЕНИЕ

Это уровень изоляции по умолчанию для InnoDB. Для согласованных чтений есть важное отличие от уровня изоляции READ COMMITTED: все согласованные чтения в рамках одной и той же транзакции считывают моментальный снимок, созданный при первом чтении. Это соглашение означает, что если вы выполняете несколько простых (неблокирующих) операторов SELECT в одной и той же транзакции, эти операторы SELECT также согласуются друг с другом.

В этой статье это очень хорошо описано.

http://www.mysqlperformanceblog.com/2012/08/28/differences-between-read-committed-and-repeatable-read-transaction-isolation-levels/

Важно помнить, что InnoDB на самом деле блокирует записи индекса, а не строки. Во время выполнения оператора InnoDB должен заблокировать каждую запись в индексе, который он просматривает, чтобы найти строки, которые он модифицирует. Это необходимо для предотвращения взаимоблокировок и поддержания уровня изоляции.

Хорошо ли индексируются таблицы? Можете ли вы запустить SHOW ENGINE innodb STATUS, чтобы убедиться, что блокировка удерживается?

person Mad Dog Tannen    schedule 12.11.2013

В mysql есть виды блокировки: блокировка на уровне строки и блокировка на уровне таблицы.

Что вам нужно, так это блокировка на уровне строк, которая позволяет читать строки за пределами тех, которые обновляются.

И чтобы реализовать блокировку на уровне строки, вы должны определить тип движка вашей таблицы как «InnoDB»:

alter table TABLE_NAME engine=innodb;
person Fengya Li    schedule 12.11.2013
comment
Думаю, это называется блокировкой уровня ROW. - person Mad Dog Tannen; 12.11.2013