16.1. Поведение #
Хотя автономные транзакции всегда выполняются внутри другой транзакции, в один момент времени может быть активна только одна транзакция; остальные должны ждать завершения активной транзакции. Когда автономная транзакция запускается, её родительская транзакция приостанавливается и помещается в стек автономных транзакций. Когда автономная транзакция фиксируется или отменяется, родительская транзакция извлекается из стека и продолжается. Завершить родительскую транзакцию можно только после завершения всех вложенных в неё автономных транзакций.
В рамках отдельной родительской транзакции можно выполнить несколько автономных, как последовательных, так и вложенных. По умолчанию Postgres Pro позволяет выполнить одновременно до 100 автономных транзакций во всех сеансах. Это ограничение можно увеличить, изменив параметр конфигурации max_autonomous_transactions. Максимальный уровень вложенности ограничен значением 128 и не может быть изменён.
Автономные транзакции не поддерживают следующие сценарии (при нарушениях выдаются ошибки):
Блокировка
FOR UPDATEне поддерживается, так что нельзя заблокировать строку в родительской транзакции и пропустить её в автономной.В автономных транзакциях не допускается обращение к временным пространствам имён.
Уровень изоляции автономных транзакций внутри блоков PL/pgSQL или PL/Python переопределить нельзя.
В автономных транзакциях не допускается использование слотов логической репликации.
Использование обёрток сторонних данных, которые полагаются на механизм транзакций PostgreSQL в автономных транзакциях, не поддерживается, за исключением адаптированного модуля
postgres_fdw. Их использование может привести к проблемам, например с обработкой ошибок во время отката транзакции.Автономные транзакции не поддерживаются со следующими расширениями:
in_memory
online_analyze
Рассмотрите следующие примеры. В них непрерывная линия обозначает активную транзакцию, а пунктирная — транзакцию, которая была приостановлена и помещена в стек автономных транзакций. Течение времени направлено вниз.
BEGIN; -- начинается обычная транзакция T0 | INSERT INTO t VALUES (1); :\ : BEGIN AUTONOMOUS TRANSACTION; -- начинается автономная транзакция : | -- T1, транзакция T0 помещается в стек : | : INSERT INTO t VALUES (2); : | : COMMIT AUTONOMOUS TRANSACTION / ROLLBACK AUTONOMOUS TRANSACTION; : | -- завершается автономная транзакция : | -- T1, транзакция T0 извлекается из стека :/ COMMIT / ROLLBACK; -- завершается транзакция T0
В зависимости от выбора из COMMIT и ROLLBACK в двух местах, следующий запрос может вернуть четыре различных результата:
SELECT sum(x) FROM t;
В одной родительской транзакции может быть несколько автономных транзакций, вложенных одна в другую или следующих друг за другом.
BEGIN; -- начинается обычная транзакция T0 | INSERT INTO t VALUES (1); :\ : BEGIN AUTONOMOUS TRANSACTION; -- начинается автономная транзакция : | -- T1, транзакция T0 помещается в стек : | : INSERT INTO t VALUES (2); : | : COMMIT AUTONOMOUS TRANSACTION / ROLLBACK AUTONOMOUS TRANSACTION; : | -- завершается автономная транзакция : | -- T1, транзакция T0 извлекается из стека :/ | :\ : BEGIN AUTONOMOUS TRANSACTION; -- начинается автономная транзакция : | -- T2, транзакция T0 помещается в стек : | : INSERT INTO t VALUES (4); : :\ : : BEGIN AUTONOMOUS TRANSACTION; -- начинается автономная транзакция : : | -- T3, транзакция T2 помещается в стек : : | : : INSERT INTO t VALUES (6); : : | : : COMMIT AUTONOMOUS TRANSACTION / ROLLBACK AUTONOMOUS TRANSACTION; : : | -- завершается автономная транзакция : : | -- T3, транзакция T2 извлекается из стека : :/ : | : COMMIT AUTONOMOUS TRANSACTION / ROLLBACK AUTONOMOUS TRANSACTION; : | -- завершается автономная транзакция : | -- T2, транзакция T0 извлекается из стека :/ COMMIT / ROLLBACK; -- завершается транзакция T0
16.1. Behavior #
Although an autonomous transaction is always run inside another transaction, only a single transaction can be active at any given moment; other transactions have to wait until the active transaction is complete. When an autonomous transaction is started, its parent transaction is paused and pushed into the autonomous transaction stack. Once the autonomous transaction is committed or rolled back, the parent transaction is popped from the stack and resumed. You cannot commit the parent transaction until all its autonomous transactions are complete.
Within a single parent transaction, you can start several autonomous ones, which can be both consecutive and nested. By default, Postgres Pro allows running up to 100 autonomous transactions in all sessions simultaneously. You can increase this limit by changing the max_autonomous_transactions configuration parameter. The maximum nesting level is restricted to 128 and cannot be changed.
Autonomous transactions do not support the following scenarios, so they will cause an error if attempted:
The
FOR UPDATElocking clause is not supported, so you cannot lock a row in a parent transaction and skip it in the autonomous transaction.Temporary namespaces cannot be accessed from autonomous transactions.
You cannot redefine isolation level for autonomous transactions within PL/pgSQL or PL/Python blocks.
Logical replication slots cannot be used in autonomous transactions.
Using foreign data wrappers that rely on PostgreSQL transaction mechanism in autonomous transactions is not supported, except for the adapted
postgres_fdw. Doing so is likely to cause errors, such as issues with error handling during transaction rollback.Autonomous transactions cannot be used together with the following extensions:
in_memory
online_analyze
Consider the following examples. A continuous line denotes an active transaction, while a dotted line denotes a transaction which has been paused and pushed into the autonomous transaction stack. Time flows downwards.
BEGIN; -- starts ordinary transaction T0 | INSERT INTO t VALUES (1); :\ : BEGIN AUTONOMOUS TRANSACTION; -- starts autonomous transaction : | -- T1, pushes T0 into stack : | : INSERT INTO t VALUES (2); : | : COMMIT AUTONOMOUS TRANSACTION / ROLLBACK AUTONOMOUS TRANSACTION; : | -- ends autonomous transaction : | -- T1, pops transaction T0 from stack :/ COMMIT / ROLLBACK; -- ends transaction T0
Depending on the two choices between COMMIT and ROLLBACK, the following query can return four different results:
SELECT sum(x) FROM t;
A parent transaction can have several autonomous transactions, which can be nested or follow one another:
BEGIN; -- starts ordinary transaction T0 | INSERT INTO t VALUES (1); :\ : BEGIN AUTONOMOUS TRANSACTION; -- starts autonomous transaction : | -- T1, pushes T0 into stack : | : INSERT INTO t VALUES (2); : | : COMMIT AUTONOMOUS TRANSACTION / ROLLBACK AUTONOMOUS TRANSACTION; : | -- ends autonomous transaction : | -- T1, pops T0 from stack :/ | :\ : BEGIN AUTONOMOUS TRANSACTION; -- starts autonomous transaction : | -- T2, pushes T0 into stack : | : INSERT INTO t VALUES (4); : :\ : : BEGIN AUTONOMOUS TRANSACTION; -- starts autonomous transaction : : | -- T3, pushes T2 into stack : : | : : INSERT INTO t VALUES (6); : : | : : COMMIT AUTONOMOUS TRANSACTION / ROLLBACK AUTONOMOUS TRANSACTION; : : | -- ends autonomous transaction : : | -- T3, pops T2 from stack : :/ : | : COMMIT AUTONOMOUS TRANSACTION / ROLLBACK AUTONOMOUS TRANSACTION; : | -- ends autonomous transaction : | -- T2, pops T0 from stack :/ COMMIT / ROLLBACK; -- ends transaction T0