Как воспроизвести "Грязное чтение"?

Рейтинг: 2Ответов: 2Опубликовано: 09.02.2023

Пытаюсь повторить ситуацию с "Грязным чтением".
БД Postgres. Две транзакции с уровнем ISOLATION_READ_UNCOMMITTED.
Первая Т1 обновляет значение в таблице.
Вторая Т2 читает это значение.
После этого Т1 падает с ошибкой и откатывается (rollback).

В результате обновленного значения от Т1 нет в БД ни в один момент времени. Это логично, ведь commit'а не было. Тогда как же воспроизвести "Грязное чтение"? Как заставить обновится значение в таблице до commit'а транзакции? Это возможно?

Ответы

▲ 6Принят

Судя по вот этому вопросу и ответам на английском СО, внутри Postgres просто нет такого уровня изоляции. Там ссылаются на документацию:

In PostgreSQL, you can request any of the four standard transaction isolation levels, but internally only three distinct isolation levels are implemented, i.e., PostgreSQL's Read Uncommitted mode behaves like Read Committed. This is because it is the only sensible way to map the standard isolation levels to PostgreSQL's multiversion concurrency control architecture.

То есть выбрать то вы уровень изоляции Read Uncommitted можете, но работать он будет всё-равно как Read Committed.

Так что никакого "грязного чтения" воспроизвести не получится, увы.

▲ 3

Цитируя книгу "PostgreSQL 15 изнутри":

За счет использования снимков данных изоляция в PostgreSQL отличается от той, что требует стандарт, и в целом она строже. Грязное чтение не допускается по определению. Формально в PostgreSQL можно указать уровень Read Uncommitted, но работать он будет точно так же, как Read Committed, поэтому дальше я вообще не буду говорить про этот уровень. Уровень Repeatable Read не допускает не только неповторяющегося, но и фантомного чтения (хотя и не обеспечивает полную изоляцию). Правда, на уровне Read Committed можно в ряде случаев потерять изменения.