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

Какие знаешь уровни изоляций транзакции в PostgreSQL?

3.0 Senior🔥 121 комментариев
#Базы данных и SQL

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

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

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

Уровни изоляции транзакций в PostgreSQL

Уровни изоляции определяют, как одновременно выполняющиеся транзакции взаимодействуют друг с другом и как они защищены от конфликтов при доступе к данным.

Стандартные уровни ISO/ANSI

PostgreSQL поддерживает четыре уровня изоляции транзакций, определённые стандартом ISO/ANSI SQL:

1. READ UNCOMMITTED (Чтение незафиксированных данных)

Это самый низкий уровень изоляции. Теоретически позволяет читать данные из незавершённых транзакций других процессов.

BEGIN ISOLATION LEVEL READ UNCOMMITTED;
SELECT * FROM users WHERE id = 1;
COMMIT;

Проблемы:

  • Dirty reads: чтение неподтверждённых данных
  • Non-repeatable reads: данные изменяются между двумя одинаковыми запросами
  • Phantom reads: появляются новые строки при повторном запросе

Важно: В PostgreSQL этот уровень трактуется как READ COMMITTED, поскольку dirty reads невозможны.

2. READ COMMITTED (Чтение подтверждённых данных) — уровень по умолчанию

Это уровень изоляции по умолчанию в PostgreSQL. Транзакция видит только данные, которые были зафиксированы до её начала.

BEGIN ISOLATION LEVEL READ COMMITTED;
SELECT * FROM users WHERE id = 1; -- видит только зафиксированные данные
COMMIT;

Характеристики:

  • Никаких dirty reads: видны только подтверждённые данные
  • Возможны non-repeatable reads: одна строка может измениться между двумя запросами
  • Возможны phantom reads: новые строки могут появиться
  • Производительность: хороший баланс между безопасностью и производительностью

3. REPEATABLE READ (Повторяемое чтение)

Отслеживает все строки, которые читаются в начале транзакции, и гарантирует, что эти строки не изменятся до конца транзакции.

BEGIN ISOLATION LEVEL REPEATABLE READ;
SELECT COUNT(*) FROM users; -- снимок на момент начала
SELECT COUNT(*) FROM users; -- тот же результат
COMMIT;

Характеристики:

  • Никаких dirty reads
  • Никаких non-repeatable reads: одна строка не изменится между запросами
  • Возможны phantom reads: могут появиться новые строки, добавленные другими транзакциями
  • Производительность: немного ниже READ COMMITTED

4. SERIALIZABLE (Сериализуемость) — максимальная безопасность

Это самый высокий уровень изоляции. Гарантирует полную сериализацию транзакций, как если бы они выполнялись последовательно.

BEGIN ISOLATION LEVEL SERIALIZABLE;
SELECT * FROM users WHERE age > 18;
INSERT INTO users (name, age) VALUES (John, 25);
COMMIT;

Характеристики:

  • Нет никаких аномалий: ни dirty reads, ни non-repeatable reads, ни phantom reads
  • Максимальная безопасность: полная предсказуемость результатов
  • Производительность: самый медленный уровень из-за дополнительной синхронизации
  • Конфликты: часто возникают ошибки сериализации (serialization failure)

Матрица проблем по уровням

ПроблемаREAD UNCOMMITTEDREAD COMMITTEDREPEATABLE READSERIALIZABLE
Dirty readsДа (эмулируется)НетНетНет
Non-repeatable readsДаДаНетНет
Phantom readsДаДаДаНет

Практические рекомендации

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

  1. READ COMMITTED (по умолчанию):

    • Для большинства приложений
    • Web-приложения с высокой конкурентностью
    • Хороший баланс безопасности и производительности
  2. REPEATABLE READ:

    • Когда нужна консистентность данных в рамках одной транзакции
    • Отчёты и аналитика
    • Сложные операции с одними и теми же данными
  3. SERIALIZABLE:

    • Критически важные финансовые операции
    • Операции, требующие абсолютной изоляции
    • Готовь к обработке ошибок сериализации
// Пример в Java с использованием Connection
Connection conn = dataSource.getConnection();
conn.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ);
try {
    // операции с БД
    conn.commit();
} catch (SQLException e) {
    conn.rollback();
}

Выбор правильного уровня изоляции критичен для масштабируемости и надёжности приложения.

Какие знаешь уровни изоляций транзакции в PostgreSQL? | PrepBro