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

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

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

История и стандартизация

Понятие уровней изоляции транзакций было формализовано в 1992 году в стандарте SQL-92 (ISO/IEC 9075:1992). До этого СУБД реализовывали различные механизмы конкурентного доступа, но без единой терминологии. Стандарт ввёл четыре классических уровня изоляции, основанных на предотвращении трёх основных аномалий конкурентного доступа: «грязного чтения», «неповторяющегося чтения» и «фантомного чтения». Впоследствии, с развитием технологий, появились и другие модели, такие как «snapshot isolation» (изоляция снимков), которая не входит в стандарт SQL-92, но широко применяется в современных СУБД (например, PostgreSQL, Oracle, Microsoft SQL Server).

Основные аномалии конкурентного доступа

Для понимания уровней изоляции необходимо определить аномалии, которые они предотвращают.

  • Грязное чтение (Dirty Read): Чтение данных, которые были изменены другой транзакцией, но ещё не зафиксированы (не выполнена команда COMMIT). Если эта транзакция впоследствии будет отменена (ROLLBACK), прочитавшие данные окажутся недействительными.
  • Неповторяющееся чтение (Non-Repeatable Read): Ситуация, когда при повторном чтении одной и той же строки данных в рамках одной транзакции возвращается другое значение. Это происходит из-за того, что параллельная транзакция успела зафиксировать изменения (UPDATE или DELETE) этой строки.
  • Фантомное чтение (Phantom Read): Ситуация, когда при повторном выполнении одного и того же запроса с условием (например, SELECT ... WHERE ...) в рамках одной транзакции возвращается разный набор строк. Это происходит из-за того, что параллельная транзакция добавила (INSERT) или удалила новые строки, удовлетворяющие условию запроса.
  • Аномалия сериализации (Serialization Anomaly): Результат параллельного выполнения набора транзакций, который не может быть получен ни при каком последовательном (сериальном) выполнении этих же транзакций. Это наиболее строгая аномалия, предотвращаемая только на самом высоком уровне изоляции.

Классические уровни изоляции по стандарту SQL-92

Стандарт SQL-92 определяет четыре уровня изоляции, каждый из которых гарантирует отсутствие определённого набора аномалий.

Read Uncommitted (Чтение незафиксированных данных)

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

Read Committed (Чтение зафиксированных данных)

Наиболее распространённый уровень изоляции в современных СУБД (например, по умолчанию в PostgreSQL, Oracle, Microsoft SQL Server). Транзакция читает только те данные, которые были зафиксированы (COMMIT) на момент начала чтения. Это предотвращает грязное чтение. Однако неповторяющееся чтение и фантомное чтение возможны, так как между двумя операциями чтения в рамках одной транзакции другая транзакция может зафиксировать изменения.

Repeatable Read (Повторяемое чтение)

Уровень, гарантирующий, что если транзакция прочитала строку, то при повторном чтении этой же строки в рамках той же транзакции она получит то же самое значение. Это предотвращает грязное чтение и неповторяющееся чтение. Однако фантомное чтение остаётся возможным, так как другие транзакции могут добавлять или удалять строки, удовлетворяющие условию запроса. В некоторых СУБД (например, в PostgreSQL) этот уровень реализован настолько строго, что также предотвращает и фантомное чтение (за счёт блокировок диапазонов или использования механизма снимков).

Serializable (Сериализуемый)

Самый высокий уровень изоляции. Гарантирует, что результат параллельного выполнения набора транзакций эквивалентен результату их последовательного выполнения в каком-либо порядке. Предотвращает все три основные аномалии, а также аномалию сериализации. Реализуется либо через строгие блокировки (включая блокировки диапазонов), либо через оптимистичные методы с проверкой конфликтов (Optimistic Concurrency Control). Обеспечивает максимальную согласованность данных, но ценой значительного снижения производительности и увеличения вероятности взаимоблокировок (deadlocks).

Реализация в различных СУБД

Хотя стандарт определяет четыре уровня, их реализация в разных СУБД может различаться.

  • PostgreSQL: По умолчанию использует Read Committed. Поддерживает Repeatable Read (который в PostgreSQL фактически предотвращает и фантомное чтение за счёт механизма многоверсионности (MVCC) и снимков данных). Serializable реализован через оптимистичный контроль конкурентного доступа (SSI — Serializable Snapshot Isolation). Read Uncommitted в PostgreSQL ведёт себя как Read Committed, так как грязное чтение невозможно по архитектурным причинам.
  • Oracle: По умолчанию использует Read Committed (на основе MVCC). Поддерживает Serializable (также на основе MVCC), но не поддерживает Repeatable Read и Read Uncommitted в классическом понимании.
  • Microsoft SQL Server: По умолчанию использует Read Committed (с блокировками). Поддерживает все четыре уровня, включая Read Uncommitted (с возможностью грязного чтения). Repeatable Read и Serializable реализованы через блокировки. Также поддерживает изоляцию снимков (Snapshot Isolation) как дополнительный уровень, не входящий в стандарт.
  • MySQL (InnoDB): По умолчанию использует Repeatable Read. Поддерживает Read Uncommitted, Read Committed, Repeatable Read и Serializable. Реализация основана на MVCC и блокировках.

Выбор уровня изоляции

Выбор уровня изоляции является компромиссом между согласованностью данных и производительностью.

  • Read Uncommitted подходит для систем, где точность данных не критична, а скорость важна (например, логирование, аналитика в реальном времени с допустимой погрешностью).
  • Read Committed — хороший баланс для большинства приложений, где требуется видеть только зафиксированные данные, но допустимы изменения между запросами.
  • Repeatable Read необходим для операций, где требуется согласованность данных в рамках одной транзакции (например, финансовые отчёты, расчёты).
  • Serializable используется для критически важных операций, где требуется строгая согласованность и невозможность аномалий (например, банковские переводы, бронирование билетов).

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

Критика и альтернативы

Стандарт SQL-92 подвергался критике за то, что он не охватывает все возможные аномалии конкурентного доступа. Например, аномалия «потерянного обновления» (Lost Update) не была явно включена в стандарт, хотя она может возникать на многих уровнях. Кроме того, реализация уровней изоляции в разных СУБД не всегда соответствует стандарту, что может приводить к неожиданному поведению при переносе приложений.

В качестве альтернативы классическим уровням изоляции были предложены более гибкие модели, такие как Snapshot Isolation (изоляция снимков), которая обеспечивает непротиворечивый снимок данных на момент начала транзакции, предотвращая грязное и неповторяющееся чтение, а также фантомное чтение, но не предотвращает аномалию сериализации. Также существуют оптимистичные методы (Optimistic Concurrency Control), которые не блокируют данные, а проверяют конфликты на этапе фиксации транзакции.

Источники

  1. ISO/IEC 9075:1992, Information technology — Database languages — SQL.
  2. Gray, J., & Reuter, A. (1993). Transaction Processing: Concepts and Techniques. Morgan Kaufmann.
  3. Berenson, H., Bernstein, P., Gray, J., Melton, J., O'Neil, E., & O'Neil, P. (1995). A critique of ANSI SQL isolation levels. ACM SIGMOD Record, 24(2), 1-10.
  4. Документация PostgreSQL, «Уровни изоляции транзакций».
  5. Документация Microsoft SQL Server, «Уровни изоляции (ядро СУБД)».
  6. Документация MySQL, «Уровни изоляции транзакций InnoDB».

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

На главную BFOmetr →