Поломанная транзакция при проведении

1. lishniy 132 01.06.22 12:42 Сейчас в теме
Добрый день.
Есть задача: перед и после проведения документа проводить связанные документы.
В обработке проведения код
Процедура ОбработкаПроведения(Отказ, Режим)
СоздатьДокументыПеред();
//код проведения
СоздатьДокументыПосле()
КонецПроцедуры


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

Процедура СоздатьДокумент()
//Создание документа
//Здесь происходит ошибка или вызывается исключение
КонецПроцедуры
Показать


При любой ошибке в процедуре создания документа полностью ломается транзакция и проведение основного документа ломается. Как этого можно выкрутиться?
Найденные решения
24. petleon 7 01.06.22 16:46 Сейчас в теме
(21) 1С:Предприятие 8 не поддерживает вложенных транзакций. Это значит, что, фактически, поддерживается только один уровень транзакции. То есть не существует возможности отменить действие транзакции некоторого уровня, не отменяя транзакции вышестоящего уровня.
Возможно у вас в СоздатьДокумент(1) есть ВызватьИсключение ...?
Остальные ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. ZergKRSK 129 01.06.22 12:53 Сейчас в теме
(1) не совсем понятно, в вопросе звучит проводить, в коде создание...
В любом случае как вариант:
1. Проводите документ как обычно, в некое хранилище (рег. сведений, например) записываете его.
2. Стартует обработка (можно фоново) к-рая идет в этот регистр, находит там документ и начинает делать то что у вас в процедуре. Перепроводит последовательно созданные и обрабатываемый документ (если надо).
3. Обработка затирает в регистре данные по обработанному документу.
4. winapi 60 01.06.22 13:29 Сейчас в теме
Ужас, да и еще в обработке проведения... почему нормально нельзя сделать, зачем эти костыли?
7. lishniy 132 01.06.22 13:33 Сейчас в теме
(4)Нормально - это сделать дополнительную кнопку/обработку для этого?
5. lishniy 132 01.06.22 13:31 Сейчас в теме
(2)так не получится, потому что для проведения исходного документа нужен результат движений документов, которые он создает.
Создание документов - это обработка создания и заполнения документа с последующим проведением.
проведение обработкой после тоже определенные проблемы. Так как я не смогу пропихнуть отказ в проведение основного документа.
6. FatPanzer 01.06.22 13:32 Сейчас в теме
(5)
что для проведения исходного документа нужен результат движений документов, которые он создает.
И вот уже в этом месте надо безжалостно бить программиста по рукам.
8. lishniy 132 01.06.22 13:35 Сейчас в теме
(6)вы же понимаете, что бизнес ставит задачу. Грубо говоря проводится документ продажи с одной организации, а так как бухгалтера не хотят делать руками документы, то необходимо автоматом делать документы списания с промежуточной и поступления на нужную организацию.
10. FatPanzer 01.06.22 13:41 Сейчас в теме
(8) Тогда причем тут обработка проведения? Создайте массив данных для проведения всех документов в необходимом порядке. И запускайте создание всех документов в единой транзакции, внутри которой обход массива с этими данными.
16. dehro 5 01.06.22 14:25 Сейчас в теме
(8)Когда всё будет висеть и тормозить, бизнес виноватого найдёт)) И не себя))

Это же не нужно делать при каждом проведении/перепроведении?
Например, кнопку на форму: "создать связные документы". Родительский документ сделали: провели - нажали (вроде как создать на основании) - получили связные.
17. lishniy 132 01.06.22 14:29 Сейчас в теме
(16)К сожалению - нужно делать при каждом проведении. Так как мог изменится состав документа или связанный реквизит и нужно документы обновить.
18. FatPanzer 01.06.22 14:33 Сейчас в теме
(17) Да, будет прикольно, когда при попытке уменьшения реализации вы попытаетесь уменьшить предыдущее перемещение...
15. dehro 5 01.06.22 14:21 Сейчас в теме
(0) Транзакция уже есть, новую не плодить.
В попытки вынести запись новых документов.
Только какая-то "тяжёлая" процедура получается. Наверняка есть способ упростить.
3. petleon 7 01.06.22 13:18 Сейчас в теме
(1) У вас вложенные транзакции: НачатьТранзакцию() - Попытка - СозданиеДокумента (неявная транзакция). Попробуйте при начале каждой транзакции проверять ее на активность - Если ТранзакцияАктивна() Тогда ... Тем самым выйдет нормально в исключение.
9. lishniy 132 01.06.22 13:38 Сейчас в теме
(3)Не поможет так. После выполнения СоздатьДокументыПеред() в обработке приходит активная транзакция, но уже поломанная(когда при любом обращении к бд возникает ошибка "в данной транзакции уже происходили ошибки")
11. petleon 7 01.06.22 13:45 Сейчас в теме
(9) я и говорю про СоздатьДокументыПеред() - сделайте после СоздатьДокумент(1) условие Если ТранзакцияАктивна() Тогда СоздатьДокумент(2) КонецЕсли и т.д.
12. petleon 7 01.06.22 13:46 Сейчас в теме
13. lishniy 132 01.06.22 13:50 Сейчас в теме
(12) Что то я не очень понял этот момент. Мне нужно создать док1+док2. Если при создании док2 будет ошибка, как откатить создание док1? Собственно для этого я и делаю все в транзакции и попытке
14. petleon 7 01.06.22 13:59 Сейчас в теме
(13) У вас для этого транзакция и условие на ТранзакцияАктивна().
19. lishniy 132 01.06.22 15:09 Сейчас в теме
(14) У меня всегда транзакция активна, так как обработка проведения происходит в транзакции. В общем, я хотел упрощенно описать схему чтоб было понятней, но упустил некоторые важные нюансы, из-за которых не понятно зачем вообще все делалось.
Если коротко, те которые проводят документы могут не знать, где остатки. Да, у нас программисты уже не смеются.

Процедура СоздатьДокументыПеред()

НачатьТранзакцию();
Для каждого Организация из списокОрганизаций цикл
Попытка
СоздатьДокумент1(Организация);
СоздатьДокумент2(Организация);
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
КонецПопытки; 
КонецЦикла;
КонецПроцедуры
Показать


В общем начал экспериментировать с проверкой остатков дополнительной перед проведением. Хотяб немного приблизился к тому что мне надо.

Не пойму почему при ОтменитьТранзакцию() во вложенной транзакции портит все транзакции. Видимо, все таки, прийдется выносить все на отдельную кнопку и там уже делать все что мне нужно
20. petleon 7 01.06.22 15:15 Сейчас в теме
(19) Попробуйте так:
Процедура СоздатьДокументыПеред()

Для каждого Организация из списокОрганизаций цикл
НачатьТранзакцию();
СоздатьДокумент1(Организация);
Если ТранзакцияАктивна() Тогда
СоздатьДокумент2(Организация);
Иначе
ОтменитьТранзакцию();
КонецЕсли;
Если ТранзакцияАктивна() Тогда
ЗафиксироватьТранзакцию();
Иначе
ОтменитьТранзакцию();
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Показать
21. lishniy 132 01.06.22 15:45 Сейчас в теме
(20)
Не доходит так до строки "Если ТранзакцияАктивна() Тогда",
Если ошибка при записи документа, то дальше код не выполняется.
Если СоздатьДокумент1 возвращает ложь и я отменяю транзакцию, то основная транзакция также становится поломанной. И после этого ЗафиксироватьТранзакцию() не отрабатывает с ошибкой "Транзакция не активна", хотя перед ней ТранзакцияАктивна() = истина
24. petleon 7 01.06.22 16:46 Сейчас в теме
(21) 1С:Предприятие 8 не поддерживает вложенных транзакций. Это значит, что, фактически, поддерживается только один уровень транзакции. То есть не существует возможности отменить действие транзакции некоторого уровня, не отменяя транзакции вышестоящего уровня.
Возможно у вас в СоздатьДокумент(1) есть ВызватьИсключение ...?
22. FatPanzer 01.06.22 16:00 Сейчас в теме
(20) Что за бред?
НачатьТранзакцию();
Попытка
    СоздатьДокумент1();
    СоздатьДокумент2();
    ////
    СоздатьДокумент9999();
    //
    ЗафиксироватьТранзакцию();
Исключение
    Если ТранзакцияАктивна() Тогда
        ОтменитьТранзакцию();
    КонецЕсли;
    // Другие действия по отмене дальнейшего проведения
КонецПопытки;
Показать
23. lishniy 132 01.06.22 16:39 Сейчас в теме
(22)
Так это то что было изначально, кроме проверки на активную транзакцию, которая всегда возвращает истина в любом состоянии в текущей ситуации.
Не работает так. Если ошибка при проведении документа(остатков не хватило, например) - транзакция ломается. Тоже самое, если ВызватьИсключение в процедуре.
26. lishniy 132 01.06.22 17:26 Сейчас в теме
(25) Спасибо. Все встало на свои места.
Оставьте свое сообщение

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