← Назад к вопросам

Что такое изолированность в БД?

2.0 Middle🔥 201 комментариев
#Базы данных и SQL

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI7 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Изолированность (Isolation) в базах данных

Изолированность — это одно из ключевых свойств транзакций в реляционных базах данных, входящее в акроним ACID (Atomicity, Consistency, Isolation, Durability). Изолированность гарантирует, что параллельно выполняющиеся транзакции не влияют друг на друга, и каждая из них работает с данными так, как если бы она выполнялась в системе в одиночку. Это предотвращает возникновение конфликтов и аномалий при одновременном доступе к данным.

Зачем нужна изолированность?

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

  • Потерянное обновление (Lost Update): Две транзакции читают одну и ту же запись, затем обе по очереди обновляют её. Результат первой транзакции перезаписывается второй, и её изменения теряются.
  • Грязное чтение (Dirty Read): Транзакция №1 читает данные, которые были изменены, но не зафиксированы транзакцией №2. Если транзакция №2 откатится, транзакция №1 будет работать с несуществующими («грязными») данными.
  • Неповторяющееся чтение (Non-repeatable Read): Транзакция №1 дважды читает одну и ту же запись. Между этими чтениями транзакция №2 изменяет и фиксирует эту запись. В результате два чтения в рамках одной транзакции возвращают разные данные.
  • Фантомное чтение (Phantom Read): Транзакция №1 дважды выполняет запрос с одним и тем же условием (например, SELECT * FROM users WHERE age > 30). Между этими запросами транзакция №2 добавляет, удаляет или изменяет строки, удовлетворяющие этому условию, и фиксирует изменения. В результате два запроса в рамках одной транзакции возвращают разный набор строк.

Уровни изолированности

Для баланса между строгой изоляцией (максимальная корректность) и производительностью (максимальный параллелизм) стандарт SQL определяет четыре уровня изолированности. Каждый следующий уровень строже предыдущего и предотвращает больше типов аномалий.

  1. READ UNCOMMITTED (Чтение незафиксированных данных): Самый низкий уровень. Транзакция может видеть незафиксированные изменения других транзакций. Допускает грязные, неповторяющиеся и фантомные чтения.
  2. READ COMMITTED (Чтение зафиксированных данных): Транзакция видит только зафиксированные изменения других транзакций. Предотвращает грязные чтения, но допускает неповторяющиеся и фантомные чтения. Это уровень по умолчанию в PostgreSQL и Oracle.
  3. REPEATABLE READ (Повторяемое чтение): Гарантирует, что данные, прочитанные один раз в транзакции, не изменятся при повторном чтении внутри этой же транзакции. Предотвращает грязные и неповторяющиеся чтения, но может допускать фантомные чтения (хотя в MySQL/InnoDB этот уровень также предотвращает и фантомы за счёт механизма gap locks). Уровень по умолчанию в MySQL/InnoDB.
  4. SERIALIZABLE (Упорядочиваемость): Самый строгий уровень. Транзакции выполняются так, как если бы они шли строго последовательно, одна за другой. Полностью предотвращает все описанные аномалии, но имеет наибольшие накладные расходы на блокировки и проверки, что снижает производительность и параллелизм.

Реализация в SQL (на примере MySQL и PostgreSQL)

Уровень изолированности можно задать для всей сессии или для следующей транзакции.

-- Установить уровень изолированности для следующей транзакции (MySQL/PostgreSQL)
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
START TRANSACTION;
-- ... операции с данными ...
COMMIT;

-- Установить уровень изолированности для всей текущей сессии (MySQL)
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;

-- Установить уровень изолированности для всей текущей сессии (PostgreSQL)
SET default_transaction_isolation = 'repeatable read';

-- Проверить текущий уровень (PostgreSQL)
SHOW default_transaction_isolation;
-- Проверить текущий уровень (MySQL)
SELECT @@transaction_isolation;

Механизмы обеспечения изолированности

Для реализации уровней изолированности СУБД используют два основных подхода:

  • Блокировки (Pessimistic Locking): Перед доступом к данным транзакция устанавливает блокировки (shared locks для чтения, exclusive locks для записи), чтобы другие транзакции не могли вмешаться. Это классический, но потенциально ведущий к взаимоблокировкам (deadlocks) способ.
  • Управление версиями данных (Optimistic Concurrency Control, MVCC): Каждая транзакция работает со своим снимком данных (snapshot) на момент её начала. Изменения, сделанные другими транзакциями, становятся видны только после их фиксации. Этот подход, используемый в PostgreSQL и MySQL/InnoDB (для уровней READ COMMITTED и REPEATABLE READ), обеспечивает высокий параллелизм чтения, но требует больше ресурсов для хранения версий и их последующей очистки.

Практический выбор уровня

Выбор уровня изолированности — это всегда компромисс:

  • Для финансовых операций, где критична абсолютная точность, часто выбирают SERIALIZABLE или REPEATABLE READ.
  • Для большинства веб-приложений, где допустимы небольшие временные несоответствия, оптимальным является READ COMMITTED, так как он обеспечивает хороший баланс между целостностью и производительностью.
  • READ UNCOMMITTED используется крайне редко, в основном для аналитических запросов, где не требуется абсолютная точность данных на конкретный момент.

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

Что такое изолированность в БД? | PrepBro