MySQL повторяемое чтение и потерянные обновления / фантомные чтения

Я пробовал это с MySQL Server 5.5:

1) гарантировано, что уровень изоляции транзакции - repeatable_read

2) запустил shell-1, запустил в нем транзакцию, затем прочитал значение через select

3) запустил shell-2, запустил в нем транзакцию, затем прочитал то же значение через select

4) в shell-1 обновили значение до значения +1 и зафиксировали

5) в shell-2 обновили значение до значения +1 и зафиксировали

Значение потеряло одно из своих обновлений и было увеличено только на 1.

Теперь, насколько я понимаю, RR использует общие блокировки чтения и эксклюзивные блокировки записи, что означает, что в # 4 и # 5 выше транзакции должны были быть заблокированы, но этого не произошло.

Так что либо мое понимание RR неверно, либо MySQL реализует RR другим способом. Так что же это?

РЕДАКТИРОВАТЬ: в аналогичном эксперименте также подтвердил, что транзакция RR (t1) не видит строк, вставленных в ту же таблицу другой транзакцией RR (t2), если она делает другой выбор в этой таблице даже после того, как t2 зафиксировал и перед t1 фиксирует , (Вот ссылка на этот эксперимент:http://www.databasejournal.com/features/mysql/article.php/3393161/MySQL-Transactions-Part-II---Transaction-Isolation-Levels.htm)

Означает ли это, что MySQL RR также заботится о фантомных чтениях?

 shrini100006 апр. 2012 г., 10:30
Да, и похоже, что сериализуемый MySQL использует общие блокировки чтения и эксклюзивные блокировки записи, и, следовательно, дает тупик в вышеупомянутом случае. Так что я действительно запутался, потому что вот что такое JP с Hibernate. В книге говорится: «Система, работающая в режиме повторяющейся изоляции при чтении, не допускает ни повторяющихся операций чтения, ни грязных операций чтения. Может произойти фантомное чтение. Транзакции чтения блокируют транзакции записи (но не другие транзакции чтения), а транзакции записи блокируют все другие транзакции. & Quot; (стр. 456)
 biziclop06 апр. 2012 г., 10:24
Вы пробовали сериализуемые транзакции?dev.mysql.com/doc/refman/5.1/en/…

Ответы на вопрос(1)

Решение Вопроса

MySQL на самом деле не соответствует Repeatable Read. Вы можете заставить это сделать, используя сериализуемый уровень изоляции или поставив FOR UPDATE после ваших выборов (посмотрите на пример ниже). Тогда желаемое поведение будет достигнуто. Что касается фантомного чтения, MySQL на самом деле строже, чем необходимо ...

SELECT value FROM table WHERE id = 7 FOR UPDATE;
 10 июл. 2015 г., 12:00
Просто чтобы быть уверенным: Потерянные обновления фактически возможны при использовании InnoDB с Repeatable Read из-за их несоответствующей реализации. Это правильно?
 shrini100003 мая 2012 г., 11:50
Спасибо! Не могли бы вы пож. привести ссылку на это, чтобы я мог принять это как ответ?
 03 мая 2012 г., 12:46
cs.umb.edu/~poneil/iso.pdf утверждает, что потерянные обновления невозможны при повторяемом чтении. Вы можете найти сводку на последней странице и обсуждение этой конкретной аномалии где-то посередине (просто найдите & quot; потерянное обновление & quot;). Я не могу дать вам больше ссылок, надеюсь, этого пока достаточно.
 15 июл. 2015 г., 10:11
@ Argeman Спасибо за разъяснения. У меня все еще плохое предчувствие по этому поводу. Знает ли реляционная алгебра эту конструкцию «для обновления»? Насколько я понимаю, график, какR_1(value), R_2(value), W_2(value), W_1(value) представляет потерянное обновление, так как транзакция 1 практически отменяет изменения, сделанные транзакцией 2.
 13 июл. 2015 г., 11:25
@ Басти хорошо, нет, не совсем. Это немного зависит от того, что вы имеете в виду под «потерянным обновлением»; он не будет потерян, просто будет перезаписан, что является хорошим поведением для базы данных; разница в том, что если вы посмотрите на свои данные перед их обновлением, вам придется использовать & quot; для обновления & quot; чтобы действительно быть уверенным, что это не изменилось, прежде чем вы делаете. Такое поведение не называется "потерянным обновлением".

Ваш ответ на вопрос