Ответ
По умолчанию в PostgreSQL используется уровень изоляции READ COMMITTED
.
Это один из четырех стандартных уровней изоляции, доступных в Postgres (наряду с REPEATABLE READ
, SERIALIZABLE
и READ UNCOMMITTED
, который в Postgres работает так же, как READ COMMITTED
).
Что это означает?
Ключевой принцип READ COMMITTED
: каждый отдельный запрос в транзакции видит снимок данных, актуальный на момент начала этого запроса, а не всей транзакции.
Это приводит к следующим эффектам:
- Защита от "грязного чтения" (Dirty Read): Ваша транзакция никогда не увидит данные, которые были изменены, но еще не закоммичены другой транзакцией.
- Возможность "неповторяемого чтения" (Non-Repeatable Read): Два одинаковых
SELECT
в рамках одной и той же транзакции могут вернуть разные результаты, если между ними другая транзакция успела изменить данные и зафиксировать их (COMMIT
).
Пример неповторяемого чтения:
-- Начало транзакции. Уровень по умолчанию READ COMMITTED.
BEGIN;
-- Запрос 1: видим баланс 1000
SELECT balance FROM accounts WHERE id = 1;
-- В это время другая транзакция снимает 200 и коммитит изменения.
-- Запрос 2: в той же транзакции видим уже новый баланс 800
SELECT balance FROM accounts WHERE id = 1;
COMMIT;
Чтобы избежать этого, можно установить более строгий уровень изоляции, например REPEATABLE READ
.