Вложенные транзакции
Разрешается инициировать транзакцию внутри другой транзакции. Если процедура была запущена в режиме 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;