Открыть сервис

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

Грязное чтение (англ. dirty read) — в информатике и теории баз данных ситуация, при которой транзакция считывает данные, записанные другой, ещё не завершённой (не зафиксированной) транзакцией. Данное явление относится к классу проблем параллельного доступа к данным и является одной из аномалий согласованности, возникающих при одновременной работе нескольких транзакций. Грязное чтение считается недопустимым в системах, требующих строгой изоляции транзакций, так как может привести к нарушению целостности данных, если незавершённая транзакция будет впоследствии отменена (откат).

Причины возникновения

Основной причиной грязного чтения является отсутствие или недостаточный уровень изоляции транзакций. В многопользовательских системах управления базами данных (СУБД) несколько транзакций могут выполняться одновременно, разделяя доступ к одним и тем же данным. Если одна транзакция (Транзакция A) изменяет запись, но ещё не зафиксировала изменения (не выполнила COMMIT), а другая транзакция (Транзакция B) считывает эту запись до завершения Транзакции A, то Транзакция B получает «грязные» данные. Если Транзакция A впоследствии будет отменена (выполнит ROLLBACK), данные, прочитанные Транзакцией B, окажутся недействительными, что может привести к логическим ошибкам в приложении или базе данных.

Грязное чтение возникает на самом низком уровне изоляции транзакций — Read Uncommitted (чтение незафиксированных данных). На этом уровне СУБД не блокирует записи, изменяемые другими транзакциями, и позволяет читать любые данные, независимо от их статуса.

Уровни изоляции транзакций

Для предотвращения грязного чтения и других аномалий параллельного доступа (неповторяющееся чтение, фантомное чтение) в стандарте SQL определена модель изоляции транзакций. Стандарт ANSI/ISO SQL-92 выделяет четыре уровня изоляции, различающихся по строгости:

  1. Read Uncommitted (чтение незафиксированных данных) — самый низкий уровень. Транзакция может читать данные, изменённые другими незавершёнными транзакциями. Допускает грязное чтение.
  2. Read Committed (чтение зафиксированных данных) — гарантирует, что транзакция читает только те данные, которые были зафиксированы другими транзакциями. Грязное чтение исключено, но возможны неповторяющееся чтение и фантомы.
  3. Repeatable Read (повторяемое чтение) — гарантирует, что данные, прочитанные в рамках одной транзакции, не изменятся другими транзакциями до её завершения. Исключает грязное чтение и неповторяющееся чтение, но допускает фантомное чтение.
  4. Serializable (сериализуемый) — самый высокий уровень. Транзакции выполняются так, как если бы они запускались последовательно, одна за другой. Полностью исключает все три аномалии, включая грязное чтение.

В большинстве современных СУБД (например, PostgreSQL, Oracle, Microsoft SQL Server) уровень изоляции по умолчанию установлен на Read Committed, что гарантирует отсутствие грязного чтения. Однако некоторые СУБД (например, MySQL с движком InnoDB) также используют Read Committed по умолчанию, но могут быть настроены на более низкий уровень.

Пример сценария

Рассмотрим типичный пример грязного чтения в банковской системе:

  1. Транзакция A начинает перевод средств со счёта 1 на счёт 2. Она уменьшает баланс счёта 1 на 1000 рублей, но ещё не завершила операцию (не выполнила COMMIT).
  2. Транзакция B, работающая на уровне Read Uncommitted, считывает текущий баланс счёта 1, который уже уменьшен на 1000 рублей, но изменения ещё не зафиксированы.
  3. Транзакция A по какой-либо причине отменяется (ROLLBACK), и баланс счёта 1 возвращается к исходному значению.
  4. Транзакция B, основываясь на «грязных» данных, продолжает свою работу, полагая, что на счёте 1 осталось меньше средств, чем на самом деле. Это может привести к неправильному расчёту комиссий, лимитов или к ошибочному списанию средств.

Методы предотвращения

Для предотвращения грязного чтения используются следующие механизмы:

Применение и ограничения

Грязное чтение может быть допустимо в некоторых специализированных системах, где скорость доступа к данным критичнее, чем их абсолютная точность. Например, в аналитических системах реального времени, где данные постоянно обновляются, а небольшие расхождения в значениях не влияют на итоговый результат. Однако в большинстве промышленных систем (финансовые, банковские, CRM, ERP) грязное чтение недопустимо и должно быть исключено.

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

См. также

Источники

  1. ISO/IEC 9075:1992, Information technology — Database languages — SQL. Международный стандарт, определяющий уровни изоляции транзакций.
  2. C. J. Date. An Introduction to Database Systems (8th Edition). Addison-Wesley, 2003. — Классический учебник по теории баз данных.
  3. Hector Garcia-Molina, Jeffrey D. Ullman, Jennifer Widom. Database Systems: The Complete Book (2nd Edition). Pearson, 2008. — Подробное описание параллельного доступа и аномалий.
  4. Документация PostgreSQL. Глава 13. Параллелизм и управление версиями данных. — Описание реализации MVCC и уровней изоляции в PostgreSQL.
  5. Документация MySQL. InnoDB Locking and Transaction Model. — Описание механизмов блокировок и изоляции в MySQL.

BFOmetr — база данных и аналитика по компаниям России.

На главную BFOmetr →