Уровни изоляции

Тема дорожной карты · PostgreSQL

PostgreSQL реализует все четыре уровня изоляции транзакций стандарта SQL — Read Uncommitted, Read Committed, Repeatable Read и Serializable, — хотя Read Uncommitted ведёт себя идентично Read Committed, поскольку архитектура MVCC PostgreSQL никогда не открывает незафиксированные данные другим транзакциям. Read Committed (уровень по умолчанию, управляемый параметром default_transaction_isolation) означает, что каждый оператор внутри транзакции видит только данные, зафиксированные до начала этого оператора: это допускает неповторяемые чтения, но предотвращает грязные чтения, что подходит большинству OLTP-нагрузок в реляционной базе данных. Repeatable Read предотвращает неповторяемые чтения и фантомные строки, предоставляя транзакции согласованный снимок всей реляционной базы данных на момент первого оператора, тогда как Serializable — наиболее строгий уровень — обнаруживает и прерывает транзакции, результаты которых не соответствуют ни одному последовательному порядку выполнения, обеспечивая истинную ACID-сериализуемость ценой более высокой частоты прерываний. Уровень изоляции задаётся для каждой транзакции командой BEGIN ISOLATION LEVEL SERIALIZABLE или SET TRANSACTION ISOLATION LEVEL REPEATABLE READ, а сочетание EXPLAIN ANALYZE с мониторингом pg_locks является стандартным подходом для диагностики конфликтов, связанных с изоляцией, и поиска возможностей оптимизации запросов в PostgreSQL.

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

Уровни изоляции оборачивают несколько операторов как одну атомарную единицу: BEGIN; ... ; COMMIT; (или ROLLBACK). ACID-гарантии: atomicity (всё или ничего), consistency (constraints выполнены), isolation (конкурентные txn выглядят последовательно на выбранном уровне), durability (committed = записано). Уровни изоляции: Read Committed (дефолт), Repeatable Read, Serializable (сильнейший, может требовать retry). Postgres использует MVCC: читатели не блокируют писателей и наоборот.

Когда применять

Оборачивайте multi-row бизнес-операции в транзакции — частичное состояние после крэша хуже, чем сбой. Serializable — для денежной логики, где два конкурентных update могут двойной счёт; иначе Read Committed достаточен и быстрее. SELECT ... FOR UPDATE — для явных row-локов. Savepoint (SAVEPOINT ...; ROLLBACK TO ...;) — для nested partial rollback внутри длинной транзакции.

Типичные ошибки

Ловушки Уровни изоляции: долгие транзакции блокируют VACUUM (autovacuum не освобождает, пока snapshot жив — bloat растёт); idle-in-transaction соединения (баговый ORM не делает commit/rollback); Serializable повсюду без retry-обработки (получите криптичные 40001); медленный внешний IO (HTTP-вызовы) внутри транзакции (lock держится слишком долго). Ставьте idle_in_transaction_session_timeout.

Связанные понятия

Полезные ресурсы

Проверить знания (1)

Загрузка вопросов…