повторяющееся чтение и вторая проблема с потерянными обновлениями

При повторяющемся уровне изоляции чтения по-прежнему возможна потеря обновлений (вторая проблема с потерянными обновлениями). Например. в сценарии с уровнем изоляции, установленным на RR:

1) транзакция t1 считывает данные из строки r1,

2) транзакция t2 считывает те же данные из строки r1,

3) t1 изменяет данные, считанные в #1, и фиксирует данные в r1.

4) t2 изменяет данные, считанные в #2, и фиксирует данные в r1. обновление t1 потеряно

Я попробовал это с Hibernate (уровень изоляции установлен на RR) и увидел поведение, упомянутое выше.

Почему тогда говорится, что с изоляцией RR мы не сталкиваемся со второй проблемой потерянных обновлений?


person shrini1000    schedule 30.01.2012    source источник


Ответы (2)


Вы можете сделать вывод, что в версии MySQL, которую вы использовали в этом тесте, реализация на самом деле не соответствует повторяемому чтению, как вы говорите в своем другом вопросе, потому что если вы сделали

транзакция t2 считывает те же данные из строки r1

снова на шаге 4 вместо

t2 изменяет данные, считанные в #2, и фиксирует данные в r1.

тогда t2 прочитал бы значение, сохраненное t1 на шаге 3. Таким образом, сначала у вас нет повторяющегося чтения, поэтому это не случай повторяющегося чтения с потерянным обновлением.

ANSI SQL-92 определяет уровни изоляции с точки зрения явлений: грязные чтения, неповторяемые чтения и фантомы.

а не с точки зрения блокировок, как вы подумали сначала, когда сказали

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

Это потому что

Разработчики ANSI SQL Isolation искали определение, которое допускало бы множество различных реализаций, а не только блокировку.

На самом деле одним из примеров этого является реализация READ_COMMITED из СЕРВЕР SQL.

Если для параметра READ_COMMITTED_SNAPSHOT установлено значение OFF (по умолчанию), компонент Database Engine использует общие блокировки, чтобы предотвратить изменение строк другими транзакциями, пока текущая транзакция выполняет операцию чтения. [...]

Если для параметра READ_COMMITTED_SNAPSHOT установлено значение ON, компонент Database Engine использует управление версиями строк для представления каждой инструкции согласованным с транзакциями моментальным снимком данных в том виде, в каком они существовали в начале инструкции. Блокировки не используются для защиты данных от обновлений другими транзакциями.

Потеря обновлений не является одним из этих явлений, но в Критика уровней изоляции ANSI SQL указал Аргеман в другом вопросе объясняется, что повторяющееся чтение гарантирует отсутствие потерянных обновлений:

P1 = Неповторяющиеся чтения P4 = Потерянные обновления Свободная интерпретация P2 (определяет явление, которое может привести к аномалии)

P2: r1[x]...w2[x]...((c1 or a1) and (c2 or a2) in any order)

Строгая интерпретация P2 (определяет фактическую аномалию), называемую A1,

A2: r1[x]...w2[x]...c2...r1[x]...c1

В то время как интерпретация потерянных обновлений

P4: r1[x]...w2[x]...w1[x]...c1

Дело, которое вы представляете, имеет форму:

A4: r1[x]...r2[x]...w1[x]...c1...w2[x]...c2

Сначала кажется, что это случай, когда нет неповторяющихся чтений, на самом деле t1 всегда будет считывать одно и то же значение x на протяжении всей транзакции.

Но если мы сосредоточимся на t2 и инвертируем числа, мы увидим, что это явно случай неповторяющегося чтения.

A4: r1[x]...r2[x]...w1[x]...c1...w2[x]...c2

A4: r1[x]...w2[x]...c2...w1[x]...c1 (цифры перевернуты для удобства чтения)

P2: r1[x]...w2[x]...((c1 или a1) и (c2 или a2) в любом порядке)

person gabrielgiussi    schedule 17.01.2016

Я пробовал вышеупомянутый эксперимент с MySQL и похоже, что MySQL реализует другое понятие RR: -reads">Повторяемое чтение MySQL и потерянное обновление/фантомное чтение

person shrini1000    schedule 06.04.2012