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

Как работает изоляция Serializable?

2.7 Senior🔥 91 комментариев
#Spring Framework

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

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

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

Изоляция Serializable в базах данных

Serializable — это самый высокий уровень изоляции транзакций в SQL. Он обеспечивает полную сериализацию доступа к данным, гарантируя, что одновременно выполняющиеся транзакции не создают проблем, как если бы они выполнялись последовательно.

Уровни изоляции (ACID)

Чтобы понять Serializable, нужно знать все четыре уровня изоляции:

  • READ UNCOMMITTED — самый низкий уровень
  • READ COMMITTED — чтение только подтверждённых данных
  • REPEATABLE READ — повторяемое чтение в рамках транзакции
  • SERIALIZABLE — полная изоляция (самый высокий)

Проблемы, которые решает Serializable

Dirty Read — чтение невыполненных изменений другой транзакции:

Транзакция A: UPDATE accounts SET balance = 100 WHERE id = 1 Транзакция B: SELECT balance — видит 100 ДО коммита Транзакция A: ROLLBACK — B получила некорректные данные

Non-Repeatable Read — одна строка меняется между двумя чтениями

Phantom Read — количество строк меняется при повторном чтении

Как работает Serializable

Суть Serializable: все читаемые и записываемые данные блокируются на всё время транзакции.

Connection conn = dataSource.getConnection();
conn.setTransactionIsolation(
    Connection.TRANSACTION_SERIALIZABLE
);
conn.setAutoCommit(false);

try {
    Statement stmt = conn.createStatement();
    stmt.executeUpdate("UPDATE accounts SET balance = balance - 100 WHERE id = 1");
    stmt.executeUpdate("UPDATE accounts SET balance = balance + 100 WHERE id = 2");
    conn.commit();
} catch (SQLException e) {
    conn.rollback();
}

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

Зависит от СУБД:

PostgreSQL (Serializable Snapshot Isolation, SSI)

  • Основано на снимках данных
  • Читает данные с момента начала транзакции
  • Обнаруживает конфликты между параллельными транзакциями

MySQL InnoDB (Blocking)

  • Использует блокировки на строки и диапазоны
// SELECT FOR UPDATE — явная блокировка
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(
    "SELECT * FROM accounts WHERE id = 1 FOR UPDATE"
);

SQL Server (Snapshot Isolation)

  • Читает из версий данных (Row Versioning)
  • Избегает большинства блокировок

Phantom Read и Serializable

Даже при Serializable нужно быть осторожным с диапазонными запросами. Благодаря Serializable, результаты запросов будут одинаковыми при повторном выполнении.

Производительность и когда использовать

Преимущества:

  • Максимальная надёжность данных
  • Гарантирует ACID свойства
  • Предотвращает все аномалии одновременности

Недостатки:

  • Низкая производительность (много блокировок или откатов)
  • Может привести к deadlock'ам
  • Не рекомендуется для высоконагруженных систем

Когда использовать:

  • Финансовые транзакции (переводы денег)
  • Критичные операции, где ошибки недопустимы
  • Низкая конкуренция за данные

Для большинства приложений достаточно READ COMMITTED или REPEATABLE READ с аккуратной обработкой ошибок. Вместо Serializable часто используют Optimistic Locking с version columns или Distributed Locking через Redis.

Как работает изоляция Serializable? | PrepBro