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

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

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

История и предпосылки появления

Понятие изоляции транзакций возникло в 1970-х годах с развитием реляционных баз данных и необходимостью обеспечения корректной работы многопользовательских систем. Первые теоретические основы были заложены в работах Джима Грея и других исследователей, которые описали проблемы, возникающие при параллельном выполнении транзакций. В 1992 году Международная организация по стандартизации (ISO) и Международная электротехническая комиссия (IEC) зафиксировали четыре основных уровня изоляции в стандарте SQL (SQL-92). Этот стандарт остаётся основой для большинства современных СУБД.

Проблемы параллельного доступа

При одновременном выполнении нескольких транзакций могут возникать аномалии, которые нарушают целостность данных. Основные из них:

  • Потерянное обновление (Lost Update) — возникает, когда две транзакции одновременно читают одни и те же данные, а затем изменяют их, и результат одной из транзакций перезаписывается другой. Например, две транзакции одновременно считывают значение счёта 100, каждая добавляет 50, и обе записывают 150, хотя должно быть 200.
  • «Грязное» чтение (Dirty Read)транзакция читает данные, которые были изменены другой, ещё не завершённой транзакцией. Если эта другая транзакция впоследствии откатывается, прочитанные данные оказываются некорректными.
  • Неповторяющееся чтение (Non-Repeatable Read) — при повторном чтении одних и тех же данных в рамках одной транзакции обнаруживается, что они были изменены другой завершённой транзакцией. Это означает, что первая транзакция получает разные значения в разные моменты времени.
  • Фантомное чтение (Phantom Read) — при повторном выполнении одного и того же запроса на выборку данных (например, с условием WHERE amount > 100) транзакция обнаруживает новые строки, которые были добавлены другой завершённой транзакцией. От неповторяющегося чтения отличается тем, что меняется не значение существующих строк, а сам набор строк.

Уровни изоляции по стандарту SQL

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

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

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

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

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

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

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

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

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

Дополнительные уровни и понятия

В некоторых СУБД, помимо стандартных, существуют дополнительные уровни изоляции. Например, Snapshot Isolation (Изоляция моментальных снимков) — распространённый механизм, при котором каждая транзакция видит «снимок» данных на момент её начала. Он предотвращает «грязное» чтение, неповторяющееся чтение и фантомное чтение, но не гарантирует сериализуемости (возможны аномалии, такие как потерянное обновление при определённых условиях). В Microsoft SQL Server этот уровень называется SNAPSHOT.

Также выделяют понятие Read Stability (Стабильность чтения), которое близко к Repeatable Read, но может иметь нюансы в реализации.

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

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

  • PostgreSQL: Уровень по умолчанию — Read Committed. Поддерживаются все четыре стандартных уровня, причём Repeatable Read в PostgreSQL фактически предотвращает и фантомное чтение, делая его близким к сериализуемому, но не эквивалентным. Serializable реализован на основе оптимистичного метода с обнаружением конфликтов.
  • MySQL: В зависимости от движка (InnoDB, MyISAM) реализация различается. InnoDB поддерживает все четыре уровня, причём Repeatable Read является уровнем по умолчанию и предотвращает фантомное чтение за счёт блокировки диапазонов (gap locks). Serializable реализуется через блокировки таблиц.
  • Oracle Database: Поддерживает уровни Read Committed (по умолчанию) и Serializable. Read Committed реализован через MVCC, а Serializable — через оптимистичный метод. «Грязное» чтение невозможно в принципе из-за архитектуры.
  • Microsoft SQL Server: Поддерживает все четыре стандартных уровня, а также дополнительный уровень SNAPSHOT. Уровень по умолчанию — Read Committed, но может быть настроен на использование блокировок или версионности строк.

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

Выбор уровня изоляции зависит от требований приложения к точности данных и допустимой нагрузке на систему. Для финансовых операций, где критична каждая копейка, обычно используется Serializable или Repeatable Read. Для веб-приложений, где высокая производительность важнее абсолютной точности, часто достаточно Read Committed. В системах, где данные редко меняются, но часто читаются, может быть оправдан Read Uncommitted.

Критика и ограничения

Стандартные уровни изоляции не охватывают все возможные аномалии. Например, при использовании Snapshot Isolation возможны такие аномалии, как потерянное обновление (в некоторых реализациях) и аномалии записи (write skew), когда две транзакции одновременно читают пересекающиеся данные и записывают непротиворечивые, но в совокупности нарушающие бизнес-правила результаты. Для полного решения этой проблемы требуется сериализуемый уровень или использование явных блокировок (например, SELECT ... FOR UPDATE).

Источники

  • ISO/IEC 9075-2:1999 (SQL/Foundation) — стандарт, определяющий уровни изоляции.
  • Gray, J., & Reuter, A. (1993). Transaction Processing: Concepts and Techniques. Morgan Kaufmann.
  • Bernstein, P. A., Hadzilacos, V., & Goodman, N. (1987). Concurrency Control and Recovery in Database Systems. Addison-Wesley.
  • Документация PostgreSQL, MySQL, Oracle Database, Microsoft SQL Server по управлению параллелизмом и уровням изоляции.

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

На главную BFOmetr →