16.1. Поведение
Хотя автономные транзакции всегда выполняются внутри другой транзакции, в один момент времени может быть активна только одна транзакция; остальные должны ждать завершения активной транзакции. Когда автономная транзакция запускается, её родительская транзакция приостанавливается и помещается в стек автономных транзакций. Когда автономная транзакция фиксируется или отменяется, родительская транзакция извлекается из стека и продолжается. Завершить родительскую транзакцию можно только после завершения всех вложенных в неё автономных транзакций.
В рамках отдельной родительской транзакции можно выполнить несколько автономных, как последовательных, так и вложенных. По умолчанию Postgres Pro позволяет выполнить одновременно до 100 автономных транзакций во всех сеансах. Это ограничение можно увеличить, изменив параметр конфигурации max_autonomous_transactions. Максимальный уровень вложенности ограничен значением 128 и не может быть изменён.
Автономные транзакции не поддерживают следующие сценарии (при нарушениях выдаются ошибки):
Блокировка
FOR UPDATE
не поддерживается, так что нельзя заблокировать строку в родительской транзакции и пропустить её в автономной.Если имеются временные таблицы, созданные с предложением
ON COMMIT DROP
, во вложенных автономных транзакциях не допускается использование одноимённых таблиц.Уровень изоляции автономных транзакций внутри блоков PL/pgSQL или PL/Python переопределить нельзя.
Автономные транзакции не поддерживаются со следующими расширениями:
online_analyze
pg_variables
Рассмотрите следующие примеры. В них непрерывная линия обозначает активную транзакцию, а пунктирная — транзакцию, которая была приостановлена и помещена в стек автономных транзакций. Течение времени направлено вниз.
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