Транзакции
Тема дорожной карты · PostgreSQL
Транзакция в PostgreSQL — логическая единица работы, объединяющая один или несколько SQL-операторов в атомарную, согласованную, изолированную и долговечную (ACID) операцию, гарантирующую либо полную фиксацию всех изменений, либо их полную отмену в случае сбоя. Транзакции инициируются командой BEGIN (или START TRANSACTION) и завершаются COMMIT для сохранения изменений или ROLLBACK для их отмены, что является основой корректного администрирования баз данных и проектирования приложений. Реализация MVCC (Multiversion Concurrency Control) в PostgreSQL означает, что каждая транзакция видит согласованный снимок базы данных на момент своего начала, поэтому читатели никогда не блокируют записывающих и наоборот — это ключевое преимущество PostgreSQL с точки зрения настройки производительности. Изоляция между параллельными транзакциями управляется командой SET TRANSACTION ISOLATION LEVEL, поддерживающей уровни READ COMMITTED (по умолчанию), REPEATABLE READ и SERIALIZABLE, каждый из которых предоставляет разные гарантии видимости параллельных изменений. Правильное управление транзакциями — избегание долгих транзакций, обработка ошибок с помощью SAVEPOINT и понимание порядка получения блокировок — необходимо для предотвращения взаимоблокировок и поддержания высокой пропускной способности в 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.
Связанные понятия
Полезные ресурсы
Проверить знания (2)
Загрузка вопросов…