Использование транзакций

Источник: 3.6. При использовании транзакций следует придерживаться следующей схемы обработки исключений в коде на сервере:

// 1. Начало транзакции
НачатьТранзакцию();
Попытка
// 2. Вся логика блокировки и обработки данных размещается в блоке Попытка-Исключение
Запрос = Новый Запрос(“…”);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл

КонецЦикла;

// 3. В самом конце обработки данных выполняется попытка зафиксировать транзакцию
ЗафиксироватьТранзакцию();
Исключение
// 4. В случае любых проблем с СУБД, транзакция сначала отменяется…
ОтменитьТранзакцию();
// 5. …затем проблема фиксируется в журнале регистрации…
ЗаписьЖурналаРегистрации(НСтр(“ru = ‘Выполнение операции'”), УровеньЖурналаРегистрации.Ошибка,,, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
// 6. … после чего, проблема передается дальше вызывающему коду.
ВызватьИсключение;
КонецПопытки;

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

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