Вложенные транзакции
Разрешается инициировать транзакцию внутри другой транзакции. Если процедура была запущена в режиме AUTOCOMMIT,
то команда «commit transaction» приводит к фиксации изменений только тогда, когда выполняется команда
«commit transaction» самой внешней транзакционной секции. Если же процедура была запущена в каком-то из
транзакционных режимов (EXCLUSIVE, OPTIMISTIC), то команда «commit transaction» вообще не приводит
к фиксации изменений (они должны быть зафиксированы «извне» процедуры с помощью команды «commit»), а лишь
отмечает конец секции «begin transaction». В отличие от «commit transaction», команда «rollback transaction»
всегда приводит к откату транзакции до последней команды «begin transaction».
Примечание
Режим OPTIMISTIC устарел (использовать не рекомендуется).
При подаче команды «begin transaction» автоматически создаётся особая контрольная точка в текущем канале процедуры.
Соответственно, команда «rollback transaction» будет производить свою операцию rollback до этой контрольной точки,
причём откат будет производиться и по дочерним каналам.
На этапе трансляции процедуры отслеживаются лишь экстремальные случаи несвязанных команд «rollback transaction»,
«commit transaction» и «begin transaction»: когда есть «begin transaction»
и нет ни одной команды «commit/rollback transaction» и наоборот, когда есть команды «commit/rollback transaction»
и нет ни одной «begin transaction».
В этом случае выдаётся код завершения 10085 «Несоответствие числа команд begin transaction и commit/rollback transaction».
Остальные случаи несоответствия уровней вложенности транзакций отслеживаются уже на этапе выполнения процедуры.
При обнаружении несоответствий уровней вложенности (попытка вызвать «commit/rollback transaction»
на нулевом уровне вложенности или возвращение из процедуры с ненулевым уровнем вложенности) выдаётся исключение
INVTRSTATE (идентификатор «-18») «Неверное состояние транзакции».
Пример вызова «commit transaction» на нулевом уровне вложенности:
code begin transaction; … rollback transaction; … commit transaction; return; end;
Пример возвращения из процедуры с ненулевым уровнем вложенности:
code begin transaction; … begin transaction; … rollback transaction; return; end;