Найти в Дзене
Записки о Java

Уровни изоляции транзакций в Java: теория и практика с PostgreSQL

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

В современных Java-приложениях, работающих с реляционными базами данных, корректное управление транзакциями — ключ к надёжности и согласованности данных. Особенно важно понимать уровни изоляции транзакций, которые определяют, как транзакции взаимодействуют друг с другом и какие аномалии могут возникнуть.

В этой статье мы разберём:

  • Что такое уровни изоляции транзакций;
  • Какие уровни поддерживает стандарт SQL и PostgreSQL;
  • Как управлять ими в Java 11 через JDBC;
  • Практические примеры для каждого уровня с демонстрацией поведения в PostgreSQL.

1. Теория: что такое уровень изоляции?

Уровень изоляции транзакции определяет степень, в которой одна транзакция изолирована от изменений, внесённых другими одновременно выполняющимися транзакциями. Чем выше уровень изоляции — тем меньше аномалий, но тем ниже параллелизм и производительность.

Согласно стандарту SQL-92, выделяют четыре уровня изоляции:

В современных Java-приложениях, работающих с реляционными базами данных, корректное управление транзакциями — ключ к надёжности и согласованности данных. Особенно важно понимать уровни изоляции транзакций, которые определяют, как транзакции взаимодействуют друг с другом и какие аномалии могут возникнуть.

В этой статье мы разберём:

  • Что такое уровни изоляции транзакций;
  • Какие уровни поддерживает стандарт SQL и PostgreSQL;
  • Как управлять ими в Java 11 через JDBC;
  • Практические примеры для каждого уровня с демонстрацией поведения в PostgreSQL.

1. Теория: что такое уровень изоляции?

Уровень изоляции транзакции определяет степень, в которой одна транзакция изолирована от изменений, внесённых другими одновременно выполняющимися транзакциями. Чем выше уровень изоляции — тем меньше аномалий, но тем ниже параллелизм и производительность.

Согласно стандарту SQL-92, выделяют четыре уровня изоляции:

Рисунок: уровень изолированности транзакций
Рисунок: уровень изолированности транзакций

Dirty Read — чтение незафиксированных («грязных») данных другой транзакции.
Non-Repeatable Read — повторное чтение той же строки даёт разные результаты из-за обновления другой транзакцией.
Phantom Read — повторный запрос возвращает новые строки, добавленные другой транзакцией.

2. PostgreSQL и уровни изоляции

PostgreSQL не поддерживает READ UNCOMMITTED — даже если вы его установите, СУБД автоматически понизит его до READ COMMITTED.

Фактически, PostgreSQL поддерживает три уровня:

  • READ COMMITTED (по умолчанию),
  • REPEATABLE READ,
  • SERIALIZABLE.

Важно: в PostgreSQL уровень REPEATABLE READ также предотвращает Phantom Read, что отличается от стандарта SQL. Это достигается за счёт механизма MVCC (Multi-Version Concurrency Control).

3. Управление уровнями изоляции в Java 11 через JDBC

В Java (начиная с JDBC 1.0, но особенно актуально в Java 11) уровень изоляции устанавливается через метод Connection.setTransactionIsolation(int level).

Константы из java.sql.Connection:

  • Connection.TRANSACTION_READ_UNCOMMITTED
  • Connection.TRANSACTION_READ_COMMITTED
  • Connection.TRANSACTION_REPEATABLE_READ
  • Connection.TRANSACTION_SERIALIZABLE
⚠️ Уровень изоляции применяется на уровне соединения, а не транзакции. Лучше устанавливать его до начала транзакции.

4. Практика: примеры для каждого уровня

Для демонстрации будем использовать простую таблицу:

Рисунок: структура таблицы для работы с уровнем изоляции транзакций
Рисунок: структура таблицы для работы с уровнем изоляции транзакций

И Java-код с использованием чистого JDBC (без Spring и ORM).

Общая настройка подключения

-4

Пример 1: READ COMMITTED (уровень по умолчанию)

Цель: показать non-repeatable read.

Рисунок: пример работы READ COMMITTED
Рисунок: пример работы READ COMMITTED

Пример 2: REPEATABLE READ

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

Рисунок: пример работы REPEATABLE READ
Рисунок: пример работы REPEATABLE READ
В PostgreSQL REPEATABLE READ гарантирует, что все чтения в рамках транзакции видят снимок (snapshot) базы на момент начала транзакции.

⚠️ Если T2 вставит новую строку, соответствующую условию T1 (например, word = 'hi'), и T1 выполнит SELECT ... WHERE word LIKE 'h%', то в PostgreSQL эта новая строка не появится — то есть phantom read тоже блокируется.

Пример 3: SERIALIZABLE

Цель: предотвратить любые конфликты, даже логические.

Рисунок: пример работы SERIALIZABLE, часть 1
Рисунок: пример работы SERIALIZABLE, часть 1
Рисунок: пример работы SERIALIZABLE, часть 2
Рисунок: пример работы SERIALIZABLE, часть 2

Уровень SERIALIZABLE в PostgreSQL использует Serializable Snapshot Isolation (SSI) и может откатывать транзакции при обнаружении потенциальных конфликтов.

5. Рекомендации

  • По умолчанию используйте READ COMMITTED — он балансирует между производительностью и согласованностью.
  • Для отчётов или аналитики, где важна стабильность данных — REPEATABLE READ.
  • SERIALIZABLE — только если логика приложения требует строгой сериализуемости (редко, но бывает).
  • Всегда обрабатывайте исключения при использовании SERIALIZABLE — транзакции могут откатываться.
  • Не забывайте вызывать setAutoCommit(false) и явно управлять commit()/rollback().

Заключение

Примеры, рассмотренные в статье, можно найти по адресу:
https://github.com/ShkrylAndrei/blog_yandex/blob/main/src/main/java/info/shkryl/level_isolation_transaction_second/IsolationDemo.java