повторяющееся чтение и вторая проблема с потерянными обновлениями - PullRequest
4 голосов
/ 30 января 2012

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

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

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

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

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

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

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

Ответы [ 2 ]

3 голосов
/ 17 января 2016

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

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

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

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

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

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

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

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

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

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

Фактически одним примером этого является реализация READ_COMMITED из SQL SERVER .

Если для 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

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

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) в любом порядке)

0 голосов
/ 06 апреля 2012

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

...