Распределённые данные · проверено по источникам

Грязное чтение

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

Также ищут: Dirty read · read uncommitted data

Практический смысл

Почему это важно

Один сеанс временно уменьшил остаток со 100 до 80, второй уже использовал 80 для решения по заказу, а первый затем откатился. Второе решение опиралось на чужую неподтверждённую версию. Для диагностики нужно знать момент чужой фиксации, а не только сравнивать числа в журнале. PostgreSQL 18 такую аномалию не допускает даже при запросе Read Uncommitted.

Доказательная часть

Что подтверждено

  1. Грязное чтение — наблюдение данных, изменённых другой транзакцией, которая к моменту чтения ещё не зафиксирована. Признак относится к происхождению и состоянию версии при чтении, а не к тому, выглядит ли число правдоподобным.

    Граница применимости: Определение SQL-аномалии по документации PostgreSQL 18; это описание явления, а не доступного режима грязного чтения в PostgreSQL.

  2. В системе, допускающей грязное чтение, сеанс А может временно изменить остаток со 100 до 80, сеанс Б — прочитать 80, а А — откатиться. Значение 80 не становится зафиксированным результатом этой транзакции, хотя Б уже мог принять по нему решение о заказе.

    Граница применимости: Редакторская временная последовательность для реализации, допускающей чтение чужих незавершённых изменений; PostgreSQL 18 этот сценарий чтения запрещает.

  3. PostgreSQL 18 не допускает грязных чтений ни на одном уровне изоляции. Запрошенный Read Uncommitted работает как Read Committed, поэтому одно имя более слабого уровня не даёт доступ к чужой незавершённой записи.

    Граница применимости: PostgreSQL 18, фактическая реализация уровней изоляции.

  4. Чтение транзакцией своих предшествующих изменений не является грязным чтением. В PostgreSQL 18 обычный SELECT на Read Committed видит собственные ещё не зафиксированные изменения, но не получает из этого права видеть такие же изменения другого сеанса.

    Граница применимости: PostgreSQL 18, Read Committed и разграничение собственных и чужих версий при обычном SELECT.

  5. Для грязного чтения не требуется последующий откат автора записи. Если читатель использовал чужую версию до её фиксации, а автор затем успешно выполнил COMMIT, чтение всё равно было грязным: на момент наблюдения запись оставалась неподтверждённой.

    Граница применимости: Следствие определения аномалии по моменту чтения; общий SQL-сценарий, недоступный в PostgreSQL 18.

  6. Запрет грязного чтения не закрепляет значение на всю транзакцию. В PostgreSQL 18 на Read Committed первое чтение может увидеть остаток 100, а повторное — 80, если другая транзакция уже зафиксировала изменение между ними. Это неповторяемое, а не грязное чтение.

    Граница применимости: PostgreSQL 18, два обычных SELECT одной транзакции и чужой COMMIT между ними; сама читающая транзакция строку не меняет.

Граница терминов

Не путать

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

При грязном чтении использована чужая версия до фиксации. При неповторяемом чтении два чтения одной транзакции наблюдают разные версии из-за уже зафиксированного изменения конкурента. Поэтому Read Committed может исключать первое явление и допускать второе.

Снимок видимости транзакции

Снимок задаёт видимые версии данных, а грязное чтение классифицирует наблюдение чужой незавершённой версии. В PostgreSQL 18 обычные снимки не открывают такие версии; при этом обновление снимка между командами может показывать новые зафиксированные значения.

Перед спецификацией

Что проверить

  1. Отметьте два сеанса, изменяемую строку и точный порядок записи, чтения и завершения автора записи.
  2. Установите, была ли чужая транзакция зафиксирована к моменту спорного чтения.
  3. Отличите собственные изменения читающего сеанса от данных другого сеанса.
  4. Для PostgreSQL 18 проверьте, что запрос Read Uncommitted не делает незавершённую запись другого сеанса видимой.
  5. Повторите опыт с COMMIT автора перед чтением и сопоставьте его с опытом, где чтение предшествовало завершению.
  6. После ROLLBACK проверьте не только базу, но и решение приложения, уже принятое по спорному значению.
  7. Если оба наблюдённых значения были зафиксированы до соответствующих чтений, исследуйте неповторяемое чтение и время жизни снимка.
Открытые основания

Первоисточники

  • Официальная документация

    PostgreSQL 18 Documentation: Transaction Isolation

    PostgreSQL Global Development Group · PostgreSQL 18, Chapter 13.2

    Определяет isolation phenomena и фактическое поведение PostgreSQL levels, включая Serializable.

    Открыть первоисточник
  • Первичная публикация

    The Transaction Model — Turing Award Lecture

    Microsoft Research / ACM · Jim Gray, FCRC 1999 lecture slides

    Первичный обзор transaction model, ACID, concurrency anomalies, logs и two-phase commit.

    Открыть первоисточник
  • Официальная документация

    PostgreSQL 18 Documentation: Introduction to MVCC

    PostgreSQL Global Development Group · PostgreSQL 18, Chapter 13.1

    Объясняет multiversion snapshots и границу между MVCC и explicit locking.

    Открыть первоисточник
Сообщить об ошибке

Опишите проблему — постараемся исправить как можно скорее.

Спасибо!

Получили ваше сообщение.
Подтвердите действие