Какие уровни изоляции транзакций поддерживает PostgreSQL?
PostgreSQL поддерживает четыре уровня изоляции в соответствии со стандартом SQL, но реализует их через MVCC — без блокировок для чтения. Фактически уникальных поведений три, поскольку READ UNCOMMITTED работает идентично READ COMMITTED.
| Уровень | Грязное чтение | Неповторяемое чтение | Фантомное чтение | Аномалия сериализации |
|---|---|---|---|---|
READ UNCOMMITTED |
Невозможно* | Возможно | Возможно | Возможно |
READ COMMITTED |
Невозможно | Возможно | Возможно | Возможно |
REPEATABLE READ |
Невозможно | Невозможно | Невозможно** | Возможно |
SERIALIZABLE |
Невозможно | Невозможно | Невозможно | Невозможно |
(*) В PostgreSQL READ UNCOMMITTED работает идентично READ COMMITTED — грязное чтение невозможно благодаря MVCC.
(**) В PostgreSQL на уровне REPEATABLE READ фантомное чтение также невозможно (в отличие от стандарта SQL, где оно допустимо).
READ COMMITTED (по умолчанию)
Каждый оператор видит данные, зафиксированные до начала этого оператора. Два одинаковых SELECT в одной транзакции могут вернуть разные результаты.
REPEATABLE READ
Транзакция видит данные, зафиксированные до начала транзакции. При попытке обновить строку, изменённую другой транзакцией, выбрасывается ошибка сериализации — нужно повторить транзакцию.
SERIALIZABLE
Гарантирует, что результат параллельного выполнения транзакций эквивалентен некоторому последовательному выполнению. Использует механизм Serializable Snapshot Isolation (SSI). При конфликте одна из транзакций откатывается — приложение должно быть готово к повторной попытке.
Пример
// Spring — повторная попытка при ошибке сериализации
@Transactional(isolation = Isolation.SERIALIZABLE)
@Retryable(value = CannotSerializeTransactionException.class, maxAttempts = 3)
public void criticalOperation() {
// ...
}
На собеседовании: ключевой ответ про PostgreSQL — грязное чтение невозможно даже на READ UNCOMMITTED (благодаря MVCC), а фантомное чтение невозможно уже на REPEATABLE READ (строже стандарта SQL). Обязательно упомяните, что при SERIALIZABLE приложение должно уметь повторять транзакции.