Чтение незафиксированной базы данных mvcc - PullRequest
3 голосов
/ 20 мая 2011

говорят, что я хочу выполнить следующие транзакции в режиме фиксации чтения (в postgres).

T1: r(A) -> w(A)
T2: r(A) -> w(A)

Если операции вызваны в следующем порядке:

r1(A)->r2(A)->w1(A)->c1->w2(A)->c2

Я бы ожидал, что T2 должен ждать в r (A). Потому что T1 установил бы эксклюзивную блокировку для A при первом чтении, потому что он хочет написать это позже. Но с MVCC нет никаких блокировок чтения?

Теперь у меня есть 2 вопроса:

Если я использую JDBC для чтения некоторых данных, а затем выполняю отдельную команду для вставки прочитанных данных. Как база данных узнает, что она должна сделать исключительную блокировку, когда она только читает? Насколько я знаю, увеличение блокировки чтения до блокировки записи не допускается в 2PL.

Я думаю, мои предположения неверны ... Где этот сценарий ждет или одна транзакция прервана? Чтение незафиксированных данных не должно допускать потерю обновлений, но я не вижу, как это может работать.

Я был бы счастлив, если бы кто-нибудь мог мне помочь. Спасибо

Ответы [ 3 ]

1 голос
/ 21 мая 2011

«Но с MVCC нет никаких блокировок чтения?»

MVCC - это другой зверь. В MVCC нет «блокировок», потому что в этом сценарии система поддерживает столько версий одной строки, сколько может потребоваться транзакциям, которые выполняются одновременно. «Прежнее содержимое» строки не «теряется при обновлении» (то есть физически перезаписывается и уничтожается), и, таким образом, чтобы убедиться, что читатель не видит «новые обновления», выполняется «перенаправление» запросов этого читателя на «прежний контент», который не заблокирован (отсюда и термин «изоляция моментального снимка»). Обратите внимание, что MVCC, в принципе, нельзя применять для обновления транзакций.

"Если я использую JDBC для чтения некоторых данных, а затем выполняю отдельную команду для вставки прочитанных данных. Как база данных узнает, что она должна сделать эксклюзивную блокировку, когда она только читает? Повышение блокировки чтения для записи Насколько я знаю, блокировка не разрешена в 2PL. "

Вы ошибаетесь по поводу 2PL. 2PL означает, что полученные блокировки никогда не снимаются до момента фиксации. Это не означает, что существующий замок не может быть усилен. Между прочим: именно поэтому уровни изоляции, такие как «стабильность курсора», не являются 2PL: они снимают блокировки чтения до времени фиксации.

0 голосов
/ 20 мая 2011

Я бы ожидал, что T2 должен ждать в r (A). Потому что T1 установил бы эксклюзивную блокировку для A при первом чтении, потому что он хочет написать это позже. Но с MVCC нет блокировки чтения?

Есть блокировки записи, если вы укажете for update в своих операторах выбора. В этом случае r2 (A) будет ожидать чтения, если попытается заблокировать те же строки, что и r1 (A).

http://www.postgresql.org/docs/9.0/interactive/explicit-locking.html

Деблокировка возникает, если две транзакции начинают и заканчивают запросом друг к другу уже заблокированных строк:

r11(A) -> r22(A) -> r12(A) (same as r22) vs r21(A) (same as r11) -> deadlock
0 голосов
/ 20 мая 2011

Режим транзакции по умолчанию в PostgreSQL - READ COMMITTED, однако READ COMMITTED не обеспечивает требуемый уровень сериализации.

Вы ищете уровень SERIALIZABLE транзакции.Посмотрите на команду SET TRANSACTION после прочтения документации PostgreSQL о уровнях сериализации транзакций , в частности, о режиме SERIALIZABLE .Документы PostgreSQL MVCC также стоит прочитать.

Приветствия.

...