Транзакции
Транзакции — механизм обеспечения целостности данных по принципу "все или ничего". Либо все изменения фиксируются, либо все откатываются при ошибке.
Ключевые моменты
-
Транзакция выполняется по принципу «все или ничего»: либо все изменения фиксируются, либо все откатываются при ошибке
-
Используются как неявно (платформа автоматически начинает транзакцию при модификации данных), так и явно — через вызов
НачатьТранзакцию(),ЗафиксироватьТранзакцию(),ОтменитьТранзакцию() -
Не поддерживаются вложенные транзакции. Не существует возможности отменить действие транзакции некоторого уровня, не отменяя транзакции вышестоящего уровня
-
Если в транзакции произошло исключение — её нельзя зафиксировать, даже если оно обработано
-
Вызовы
НачатьТранзакцию()иЗафиксироватьТранзакцию()/ОтменитьТранзакцию()должны быть парными и в одном методе -
При превышении количества вызовов
НачатьТранзакцию()система автоматически вызоветОтменитьТранзакцию()при завершении кода или передаче управления с сервера на клиента -
Чтение данных, как правило, выполняется вне транзакции, а модификация — внутри
Транзакции при проведении документа
Следующие событ ия выполняются в одной транзакции:
- Перед записью (модуль объекта)
- При записи (модуль объекта)
- Обработка проведения (модуль объекта)
- При записи на сервере (модуль формы)
Важно: Если в любом из этих событий возникнет исключение — вся транзакция откатится, включая запись документа и всех регистров.
Ответы на ключевые вопросы
1. Какая главная ошибка при работе с транзакциями?
Из-за неправильной работы с транзакциями возникает ошибке «В данной транзакции уже происходили ошибки». Эта ошибка не указывает на реальную причину сбоя и возникает, когда код пытается работать с уже откаченной транзакцией.
Ключевые правила:
- Инкапсуляция транзакций: Метод, начавший транзакцию, обязан её завершить (фиксацией или откатом). Нельзя начинать в одном методе, а завершать в другом.
- Обработка исключений: Любое исключение внутри транзакции должно приводить к её откату с последующим пробросом исключения выше. Начать транзакцию в одном методе, а завершить в другом. Нарушение правила парности и инкапсуляции.
2. Что будет, если в транзакции произошло исключение?
Транзакция становится "испорченной". Её нельзя зафиксировать, даже если исключение было обработано. Только откат.
3. Как правильно обрабатывать ошибки в транзакции?
НачатьТранзакцию();
Попытка
// Логика
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ВызватьИсключение; // Пробросить выше
КонецПопытки;
4. Можно ли иметь вложенные транзакции?
Нет. 1С не поддерживает вложенные транзакции. Каждая новая НачатьТранзакцию() просто увеличивает счетчик, но логически это одна транзакция.