2012-01-30 6 views
3

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

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

2) транзакция T2 читает одни и те же данные из ряда R1,

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

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

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

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

ответ

2

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

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

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

t2 модифицирует данные, считываемые в # 2 и фиксирует данные в Г1.

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

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

, а не в терминах замков, как вы думали, на первый when you said

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

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

Дизайнеры изоляции ANSI SQL искали определение, которое допускало бы многие различные реализации, а не только блокировка.

Фактически, одним из примеров является READ_COMMITED implementation from SQL SERVER.

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

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

потерянных обновлений не одна из этого явления, но в A Critique of ANSI SQL Isolation Levels указывал Argeman в the other question объясняется тем, что repeteable чтение гарантирует отсутствие потерянных обновлений:

P1 = Non-repeteable читает P4 = Потерянные обновления свободная интерпретация P2 (определяет феномен, который может привести к аномалии) является

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

строгое толкование P2 (определяет фактическое Anom Aly), называется А1

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 [х] ... r2 [х] ... w1 [х] ... c1 ... w2 [х] ... c2

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

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