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

Уровень изолированности Serializable

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

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

Концепция уровней изолированности транзакций была впервые формализована в 1992 году в стандарте ANSI/ISO SQL-92. В этом стандарте были определены четыре уровня изолированности: Read Uncommitted, Read Committed, Repeatable Read и Serializable. Serializable был задуман как самый строгий уровень, обеспечивающий максимальную согласованность данных ценой потенциального снижения производительности из-за блокировок или откатов транзакций.

В 1995 году исследователи Х. Беренсон, Ф. Бернштейн и другие в своей работе «A Critique of ANSI SQL Isolation Levels» показали, что стандартные определения уровней изолированности, основанные на феноменах (аномалиях), недостаточно точны. Они предложили более строгие формальные определения, основанные на понятии сериализуемости. Впоследствии многие современные СУБД (PostgreSQL, Oracle, Microsoft SQL Server) реализовали Serializable, используя не только блокировки, но и механизмы оптимистичного управления параллелизмом (Optimistic Concurrency Control, OCC) и снимки состояния (snapshot isolation), хотя последний сам по себе не гарантирует полной сериализуемости.

Механизмы реализации

Реализация уровня Serializable зависит от архитектуры СУБД и используемой модели управления параллелизмом. Существует два основных подхода:

Пессимистическая блокировка (Pessimistic Locking)

При этом подходе СУБД блокирует все ресурсы (строки, страницы, таблицы), к которым обращается транзакция, на всё время её выполнения. Другие транзакции, пытающиеся изменить те же данные, вынуждены ждать завершения блокирующей транзакции. Это предотвращает любые конфликты, но может приводить к взаимоблокировкам (deadlocks) и снижению пропускной способности системы при высокой конкуренции. Примеры СУБД, использующих этот подход по умолчанию для Serializable: Microsoft SQL Server (при использовании блокировок на уровне строк), IBM Db2.

Оптимистическая блокировка (Optimistic Locking) и проверка сериализуемости

Этот подход, часто реализуемый через механизм снимков (snapshot isolation), позволяет транзакциям выполняться без блокировок, работая с версией данных на момент начала транзакции. При попытке фиксации (commit) СУБД проверяет, не было ли конфликтов с другими транзакциями, которые могли бы нарушить сериализуемость. Если конфликт обнаружен, транзакция откатывается (rollback) и может быть повторена. Этот метод снижает количество блокировок, но увеличивает число откатов при высокой конкуренции. Примеры: PostgreSQL (режим Serializable, начиная с версии 9.1, использует Serializable Snapshot Isolation — SSI), Oracle (режим Serializable, хотя на практике он часто эквивалентен Snapshot Isolation с дополнительными проверками).

Гарантии и аномалии

Уровень Serializable гарантирует отсутствие следующих аномалий:

  1. Грязное чтение (Dirty Read): Чтение данных, изменённых незавершённой транзакцией.
  2. Неповторяющееся чтение (Non-repeatable Read): Ситуация, когда при повторном чтении одной и той же строки в рамках одной транзакции получаются разные значения (из-за изменений, внесённых другой завершённой транзакцией).
  3. Фантомное чтение (Phantom Read): Ситуация, когда при повторном выполнении одного и того же запроса с условием (например, WHERE amount > 100) в рамках одной транзакции появляются новые строки (фантомы), добавленные другой завершённой транзакцией.
  4. Аномалия сериализации (Serialization Anomaly): Ситуация, когда результат параллельного выполнения транзакций не эквивалентен никакому последовательному порядку их выполнения. Это наиболее общая аномалия, которую Serializable устраняет.

Применение

Уровень изолированности Serializable применяется в сценариях, где критична высокая согласованность данных и допустимы потенциальные задержки или откаты транзакций. Типичные области использования:

  • Финансовые системы: Переводы средств, расчёты балансов, начисление процентов, где любое искажение данных недопустимо.
  • Бухгалтерский учёт: Формирование отчётов, аудиторские проверки, где требуется точное отражение состояния на момент транзакции.
  • Системы бронирования: Бронирование авиабилетов, гостиниц, билетов на мероприятия, где необходимо избежать двойного бронирования одного и того же ресурса.
  • Управление запасами: Списание товаров со склада, где одновременные заказы не должны приводить к отрицательному остатку.
  • Научные и статистические расчёты: Обработка данных, где требуется строгая согласованность промежуточных результатов.

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

Несмотря на свои преимущества, уровень Serializable имеет ряд недостатков:

  • Снижение производительности: Из-за блокировок или частых откатов транзакций пропускная способность системы может значительно снижаться по сравнению с менее строгими уровнями изоляции (например, Read Committed).
  • Взаимоблокировки (Deadlocks): При использовании пессимистической блокировки возрастает вероятность взаимоблокировок, которые требуют вмешательства СУБД (автоматический откат одной из транзакций).
  • Сложность реализации: Реализация полной сериализуемости (особенно через SSI) является сложной задачей для разработчиков СУБД и может потребовать значительных вычислительных ресурсов.
  • Необходимость повторных попыток: При оптимистическом подходе приложения должны быть готовы к тому, что транзакция будет откачена, и её необходимо повторить.

Альтернативы

Для приложений, где требования к согласованности не столь высоки, используются более слабые уровни изоляции:

  • Read Uncommitted: Допускает грязное чтение.
  • Read Committed: Гарантирует отсутствие грязного чтения, но допускает неповторяющееся и фантомное чтение.
  • Repeatable Read: Гарантирует отсутствие грязного и неповторяющегося чтения, но допускает фантомное чтение (в некоторых реализациях, например, в PostgreSQL, Repeatable Read также предотвращает фантомы, но не гарантирует полной сериализуемости).

Примеры в российских СУБД

В российских СУБД, таких как Postgres Professional (разработчик дистрибутива PostgreSQL для России) и СУБД «Линтер», уровень изолированности Serializable реализован в соответствии с международными стандартами. В PostgreSQL, который является основой для многих российских продуктов, Serializable реализован через механизм Serializable Snapshot Isolation (SSI), начиная с версии 9.1. В СУБД «Линтер» также поддерживается данный уровень, хотя его реализация может отличаться в деталях.

Источники

  1. Стандарт ANSI/ISO SQL-92 (ISO/IEC 9075:1992).
  2. Berenson, H., Bernstein, P., et al. «A Critique of ANSI SQL Isolation Levels». Proceedings of the 1995 ACM SIGMOD International Conference on Management of Data.
  3. Gray, J., & Reuter, A. «Transaction Processing: Concepts and Techniques». Morgan Kaufmann, 1993.
  4. Документация PostgreSQL: «Chapter 13. Concurrency Control» (раздел 13.2.4. Serializable Isolation Level).
  5. Документация Microsoft SQL Server: «Isolation Levels in the Database Engine».
  6. Документация Oracle Database: «Data Concurrency and Consistency» (раздел «Serializable Isolation»).

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

На главную BFOmetr →