Фиксируйся транзакция большая и маленькая!

Платформа 1С не поддерживает вложенные транзакции, но разработчик может использовать вложенность транзакций при написании кода. По факту будет существовать только один уровень транзакций. Такое поведение платформы накладывает ограничение: не существует возможности отменить действие транзакции некоторого уровня, не отменяя транзакции вышестоящего уровня.

В рамках уже выполняемой транзакции можно обращаться к методам:
  • НачатьТранзакцию();
  • ЗафиксироватьТранзакцию();
  • ОтменитьТранзакцию().
Вызов метода НачатьТранзакцию() при выполняемой транзакции не окажет никакого влияния на работу системы, просто произойдет увеличение значения счетчика транзакций на 1. Данный метод начинает новую транзакцию только в том случае, если значение счетчика транзакций равно 0.

Вызов метода ЗафиксироватьТранзакцию() для вложенной транзакции  не производит реального фиксирования транзакции. Фиксирование результата выполнения всей транзакции в целом происходит в том случае, если значение счетчика транзакций будет равно 1 (т.е. выполняется фиксирование транзакции самого верхнего уровня), иначе просто произойдет уменьшение значения счетчика транзакций на 1. Если же вызвать метод при счетчике транзакций равном 0, произойдет исключительная ошибка.

Вызов метода ОтменитьТранзакцию() для вложенной транзакции фиксирует факт отмены транзакции (реального отката транзакции в этот момент не происходит), что приводит к невозможности фиксации результатов транзакции верхнего уровня, иначе говоря, вся транзакция завершится откатом.  Данный метод уменьшает значение счетчика транзакций на 1 и устанавливает признака отмены всей транзакции в целом. Обращение к методу ЗафиксироватьТранзакцию() после отмены вложенной транзакции в итоге приведет к отмене транзакции.

Если транзакция верхнего уровня не завершена, то она автоматически завершится отменой!

Будьте внимательны: ошибка базы данных, произошедшая при значении счетчика транзакций большем 1, т.е. произошла ошибка во вложенной транзакции, приведет к невозможности продолжения и фиксации всей транзакции в целом, даже если вы перехватите ошибку.

НачатьТранзакцию(); // Счетчик транзакций увеличивается на 1.
Попытка
ДокОбъект1.Записать(); // Здесь произошла ошибка записи.
Исключение
КонецПопытки;
Попытка
ДокОбъект2.Записать();
Исключение
КонецПопытки;
// Из-за ошибки базы данных по факту произойдет отмена транзакции.
ЗафиксироватьТранзакцию(); // Счетчик транзакций уменьшается на 1.


НО, ошибки не связанные с базой данных (допустим, вы случайно поделили на 0), никак не влияют на выполнение транзакции.

Вывод: фактически, имеется одна транзакция, и в ней обеспечивается принцип "все или ничего", включая все вложенные транзакции. Чтобы транзакция была нормально завершена (зафиксирована), должны быть нормально завершены (зафиксированы) транзакции всех уровней, а чтобы транзакция была отменена, достаточно отменить транзакцию любого уровня.

Комментарии