Вложенные транзакции

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