Несоответствие в повторяемом чтении

10

http://www.postgresql.org/docs/9.2/static/transaction-iso.html

Режим повторяемого чтения обеспечивает строгую гарантию того, что каждая транзакция видит полностью стабильное представление базы данных. Тем не менее, это представление не всегда будет соответствовать последовательному (по одному) выполнению параллельных транзакций одного и того же уровня. Например, даже транзакция только для чтения на этом уровне может видеть контрольную запись, обновленную, чтобы показать, что пакет был завершен, но не увидеть одну из подробных записей, которая логически является частью пакета, потому что она прочитала более раннюю версию контрольной записи. , Попытки обеспечить выполнение бизнес-правил транзакциями, выполняющимися на этом уровне изоляции, вряд ли будут работать правильно без осторожного использования явных блокировок для блокировки конфликтующих транзакций.

Разве это не фантомное чтение, которое невозможно в режиме повторяющегося чтения?

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

Алиса
источник

Ответы:

5

Вот мое чтение этого раздела. Я признаю, что это сбивает с толку.

Предположим, у меня есть две таблицы:

CREATE TABLE batch (
   id serial not null unique,
   control_code text primary key,
   date_posted date not null default now()
);

CREATE TABLE details (
   batch_id int not null references batch(id),
   description text,
   primary key(batch_id, description)
);

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

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

Крис Траверс
источник
3

В вики PostgreSQL есть документ , показывающий некоторые проблемы, которые могут возникнуть с определенными комбинациями транзакций на уровне изоляции транзакций REPEATABLE READ, и как их избежать на уровне изоляции транзакций SERIALIZABLE, начиная с PostgreSQL версии 9.1.

Он также включает пример того, как транзакция REPEATABLE READ-level READ-ONLY может считывать противоречивые данные.

девятьсот седьмой
источник
@dezso Вас это может заинтересовать
907
1

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

Когда вы выбираете уровень Read Uncommitted, вы действительно получаете Read Committed, и фантомные чтения невозможны в реализации Regatable Read в PostgreSQL , поэтому фактический уровень изоляции может быть более строгим, чем тот, который вы выбираете.

Теперь, что насчет этого предостережения: «эта точка зрения не обязательно всегда будет соответствовать некоторому последовательному (по одному) выполнению параллельных транзакций одного и того же уровня»? Я думаю (я не уверен), что это означает, что это означает, что снимок «извне» (исправленный в начале транзакции) может в конечном итоге включать строки из других транзакций, но не включать некоторые другие строки из той же транзакции.

leonbloy
источник