Не получается обработать исключение внутри транзакции

1. iRounder 104 05.06.24 13:07 Сейчас в теме
8.2
В общем модуле есть процедура1, в ней начинается транзакция, в которой вызывается функция1.
В фукнции1 есть цикл, в котором в Попытке создаются документы. И в случае, если при создании и проведении документа возникает ошибка, то я попадаю в Исключение, но обработать его не могу, потому что работа останавливается с сообщением "В данной транзакции уже происходили ошибки", т.о. я не могу ни записать ошибку в лог, ни вывести ее на экран. Более того после обработки исключения по задумке мы возвращаем в процедуру1 ответ, получив который, должны отменить транзакцию и отправить письмо на электронную почту. Но понятно, что до этого момента не доходит из-за "В данной транзакции уже происходили ошибки".
Есть ли в такой ситуации все-таки возможность "красиво" обработать исключение?
По теме из базы знаний
Ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. soft_wind 05.06.24 13:22 Сейчас в теме
как старший брат, ипользуйте переменную Отказ
возвращайте ее на верхний уровень и обрабатывайте
Если Отказ Тогда ...
3. iRounder 104 05.06.24 13:26 Сейчас в теме
Не совсем понял варианта. Отказ же может "возникнуть" во многих процедурах и функциях обработки записи и проведения документа, как в модуле объекта документа, так и в различных подписках.
4. Bukaska 147 05.06.24 13:27 Сейчас в теме
(3)Вы бы привели пример функции что-ли? дали бы код.
А то это все иначе как гадание на кофейной гуще)))
5. iRounder 104 05.06.24 13:35 Сейчас в теме
(4) Там тысячи строк кода :)
Если в двух словах - то так:

Процедура Процедура1()
    НачатьТранзакцию();
    ...
    Если Не Функция1() Тогда
        ОтменитьТранзакцию();
        ОтправитьПисьмо("Ошибка");
    Иначе
        ЗафиксироватьТранзакцию();
    КонецЕсли
КонецПроцедуры

Функция1()
    ...
    Для Сч = 1 По КоличествоДокументов Цикл
        ... //Создание и заполнение документа
        Попытка
            НовыйДокумент.Записать();
        Исключение
            Сообщить(ОписаниеОшибки());
            ЗаписатьВЛог(ОписаниеОшибки());
            Возврат Ложь;
        КонецПопытки
    КонецЦикла;
    Возврат Истина;
КонецФункции
Показать
10. spacecraft 05.06.24 13:53 Сейчас в теме
(5) не нужно делать в цикле попытку для каждого документа.
Попытку перенести на уровень основной транзакции. Соответственно в исключении получать ошибку и делать с ней что нужно
o.kovalev; +1 Ответить
11. iRounder 104 05.06.24 13:58 Сейчас в теме
(10)
Попытку перенести на уровень основной транзакции. Соответственно в исключении получать ошибку и делать с ней что нужно

В примере я привел простейший пример кода.
В реальной реализации в обработке исключения попытки выдается и другая информация, кроме самого описания ошибки, сгенерированной системой, и эта информация доступна только во "внутренней" функции и для каждого типа документа (или другого объекта) она своя.
12. spacecraft 05.06.24 14:09 Сейчас в теме
(11) обработкой исключения внутри функции для каждого документа просто скрываете ошибку и основная ошибка далее не идет.
Тогда в основной функции все равно делайте попытку и обрабатывайте там исключение, а в обработке исключения по документам пробрасывайте исключение дальше. Можно со своим текстом ошибки, который получит основной обработчик исключения в основной попытке.
13. iRounder 104 05.06.24 14:10 Сейчас в теме
(12) Буду пробовать. Спасибо.
6. o.kovalev 117 05.06.24 13:38 Сейчас в теме
С 1С ИТС пример
Правильно

 НачатьТранзакцию();
    Попытка
        РегистрыСведений.КурсыВалют.УстановитьИспользованиеИтогов(Ложь);
       
        НаборЗаписей = РегистрыСведений.КурсыВалют.СоздатьНаборЗаписей();
        НаборЗаписей.Отбор.Валюта.Установить(ВалютаСсылка);
        НаборЗаписей.Загрузить(ТаблицаКурсов);
        НаборЗаписей.ОбменДанными.Загрузка = Истина;
       
        НаборЗаписей.Записать();
       
        РегистрыСведений.КурсыВалют.УстановитьИспользованиеИтогов(Истина);
       
        ЗафиксироватьТранзакцию();
    Исключение
        ОтменитьТранзакцию();
        ВызватьИсключение;
    КонецПопытки;
Показать
7. iRounder 104 05.06.24 13:42 Сейчас в теме
(6) В примере транзакция и попытки в рамках одной процедуры.
У меня транзакция одна на множество процедур и функций - обусловлено решаемой задачей.
Остается попробовать начало и фиксацию транзакции оставить в общей процедуры, а отменять ее при необходимости в каждой "внутренней" процедуре и функции.
8. o.kovalev 117 05.06.24 13:49 Сейчас в теме
(7) Но ведь транзакция должна завершиться вся , иначе зачем вообще она ?
9. iRounder 104 05.06.24 13:51 Сейчас в теме
(8) Не вижу противоречий. В общей процедуре начало транзакции и ее фиксация в случае успешного выполнения всех "внутренних" функций, в случае ошибки в любой из них - отмена общей транзакции внутри функции, вызвавшей исключение.
14. iRounder 104 05.06.24 14:11 Сейчас в теме
Спасибо всем отозвавшимся, буду пробовать накинутые варианты.
15. spacecraft 05.06.24 14:15 Сейчас в теме
и еще. По хорошему транзакцию начинать нужно для записи уже подготовленных для записи документов.
Сначала создаете коллекцию ДокументОбъект с заполненными данными. Потом открываете транзакцию и в цикле проходите коллекцию и записываете.
Время транзакции желательно делать как можно меньше.
16. iRounder 104 05.06.24 14:20 Сейчас в теме
(15) Я это знаю. Но вопрос специфики решаемой задачи. В транзакции не только создаются документы, до их создания еще записывается в разные регистры полученные извне данные, на основании которых и заполняются документы. И только в случае успешного выполнения всего кода данные должны попасть в БД. Поэтому это все в одной транзакции, и в 99% случаев она выполняется регламентно в то время, когда с БД никто не работает.
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот