Вложенность транзакций

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

Если транзакция уже начата, то вызов начала транзакции не выдает ошибки, но и не оказывает никакого влияния на работу системы. Однако система запоминает, что был вызов начала вложенной транзакции, чтобы соответственно "проигнорировать" и завершение транзакции данного уровня.

При вызове завершения вложенной транзакции реального завершения транзакции также не происходит. Система отмечает, что уровень транзакции уменьшился. Реальное завершение транзакции происходит только при вызове завершения транзакции на самом верхнем уровне.

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

Приведем пример:

Копировать в буфер обмена
 НачатьТранзакцию();
 Объект1 = Справочники.Справочник1.СоздатьЭлемент(); 
 Объект1.Записать();
 НачатьТранзакцию();
 Объект2 = Справочники.Справочник1.СоздатьЭлемент(); 
 Объект2.Записать();
 ЗафиксироватьТранзакцию();

В этом примере не будет записан ни Объект1, ни Объект2, так как не зафиксирована транзакция верхнего уровня. И она автоматически будет завершена откатом.

Приведем другой пример:

Копировать в буфер обмена
 НачатьТранзакцию();
 Объект1 = Справочники.Справочник1.СоздатьЭлемент(); 
 Объект1.Записать();
 НачатьТранзакцию();
 Объект2 = Справочники.Справочник1.СоздатьЭлемент(); 
 Объект2.Записать();
 ОтменитьТранзакцию();
 ЗафиксироватьТранзакцию();

Здесь также не будут записаны оба объекта, потому, что вложенная транзакция отменена.

Приведем третий пример:

Копировать в буфер обмена
 НачатьТранзакцию();
 Объект1 = Справочники.Справочник1.СоздатьЭлемент(); 
 Объект1.Записать();
 НачатьТранзакцию();
 Объект2 = Справочники.Справочник1.СоздатьЭлемент(); 
 Объект2.Записать();
 ЗафиксироватьТранзакцию();
 ЗафиксироватьТранзакцию();

Здесь будут записаны оба объекта, потому, что зафиксированы транзакции обоих уровней и не было отмены транзакции.

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

Следует иметь в виду, что при записи объектов и наборов записей система сама инициирует и фиксирует транзакцию, поэтому в обработчиках, например, таких как ПередЗаписью, фактически, транзакция уже начата, а по завершению обработчика транзакция фиксируется или отменяется в зависимости от значения параметра Отказ.

Также имеет смысл ознакомиться со статьей "Ошибки базы данных и транзакции".