Добрый день.
Есть задача: перед и после проведения документа проводить связанные документы.
В обработке проведения код

```1c
    Процедура ОбработкаПроведения(Отказ, Режим)
    СоздатьДокументыПеред();
    //код проведения
    СоздатьДокументыПосле()
    КонецПроцедуры
```

Создание документов вынесена в общий модуль. Грубо говоря, код такой

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

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

При любой ошибке в процедуре создания документа полностью ломается транзакция и проведение основного документа ломается. Как этого можно выкрутиться?
---
1С:Предприятие 8 не поддерживает вложенных транзакций. Это значит, что, фактически, поддерживается только один уровень транзакции. То есть не существует возможности отменить действие транзакции некоторого уровня, не отменяя транзакции вышестоящего уровня.
Возможно у вас в СоздатьДокумент(1) есть ВызватьИсключение ...?
---
https://habr.com/ru/post/419715/
---
не совсем понятно, в вопросе звучит проводить, в коде создание...
В любом случае как вариант:
1. Проводите документ как обычно, в некое хранилище (рег. сведений, например) записываете его.
2. Стартует обработка (можно фоново) к-рая идет в этот регистр, находит там документ и начинает делать то что у вас в процедуре. Перепроводит последовательно созданные и обрабатываемый документ (если надо).
3. Обработка затирает в регистре данные по обработанному документу.
---
Ужас, да и еще в обработке проведения... почему нормально нельзя сделать, зачем эти костыли?
---
Нормально - это сделать дополнительную кнопку/обработку для этого?
---
так не получится, потому что для проведения исходного документа нужен результат движений документов, которые он создает.
Создание документов - это обработка создания и заполнения документа с последующим проведением.
проведение обработкой после тоже определенные проблемы. Так как я не смогу пропихнуть отказ в проведение основного документа.
---
что для проведения исходного документа нужен результат движений документов, которые он создает. И вот уже в этом месте надо безжалостно бить программиста по рукам.
---
вы же понимаете, что бизнес ставит задачу. Грубо говоря проводится документ продажи с одной организации, а так как бухгалтера не хотят делать руками документы, то необходимо автоматом делать документы списания с промежуточной и поступления на нужную организацию.
---
Тогда причем тут обработка проведения? Создайте массив данных для проведения всех документов в необходимом порядке. И запускайте создание всех документов в единой транзакции, внутри которой обход массива с этими данными.
---
Когда всё будет висеть и тормозить, бизнес виноватого найдёт)) И не себя))

Это же не нужно делать при каждом проведении/перепроведении?
Например, кнопку на форму: "создать связные документы". Родительский документ сделали: провели - нажали (вроде как создать на основании) - получили связные.
---
К сожалению - нужно делать при каждом проведении. Так как мог изменится состав документа или связанный реквизит и нужно документы обновить.
---
Да, будет прикольно, когда при попытке уменьшения реализации вы попытаетесь уменьшить предыдущее перемещение...
---
Транзакция уже есть, новую не плодить.
В попытки вынести запись новых документов.
Только какая-то "тяжёлая" процедура получается. Наверняка есть способ упростить.
---
У вас вложенные транзакции: НачатьТранзакцию() - Попытка - СозданиеДокумента (неявная транзакция). Попробуйте при начале каждой транзакции проверять ее на активность - Если ТранзакцияАктивна() Тогда ... Тем самым выйдет нормально в исключение.
---
Не поможет так. После выполнения СоздатьДокументыПеред() в обработке приходит активная транзакция, но уже поломанная(когда при любом обращении к бд возникает ошибка "в данной транзакции уже происходили ошибки")
---
я и говорю про СоздатьДокументыПеред() - сделайте после СоздатьДокумент(1) условие Если ТранзакцияАктивна() Тогда СоздатьДокумент(2) КонецЕсли и т.д.
---
и попытку уберите
---
Что то я не очень понял этот момент. Мне нужно создать док1+док2. Если при создании док2 будет ошибка, как откатить создание док1? Собственно для этого я и делаю все в транзакции и попытке
---
У вас для этого транзакция и условие на ТранзакцияАктивна().
---
У меня всегда транзакция активна, так как обработка проведения происходит в транзакции. В общем, я хотел упрощенно описать схему чтоб было понятней, но упустил некоторые важные нюансы, из-за которых не понятно зачем вообще все делалось.
Если коротко, те которые проводят документы могут не знать, где остатки. Да, у нас программисты уже не смеются.

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

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

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

Не пойму почему при ОтменитьТранзакцию() во вложенной транзакции портит все транзакции. Видимо, все таки, прийдется выносить все на отдельную кнопку и там уже делать все что мне нужно
---
Попробуйте так:

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

    Для каждого Организация из списокОрганизаций цикл
    НачатьТранзакцию();
    СоздатьДокумент1(Организация);
    Если ТранзакцияАктивна() Тогда
    СоздатьДокумент2(Организация);
    Иначе
    ОтменитьТранзакцию();
    КонецЕсли;
    Если ТранзакцияАктивна() Тогда
    ЗафиксироватьТранзакцию();
    Иначе
    ОтменитьТранзакцию();
    КонецЕсли;
    КонецЦикла;
    КонецПроцедуры
```
---
Не доходит так до строки "Если ТранзакцияАктивна() Тогда",
Если ошибка при записи документа, то дальше код не выполняется.
Если СоздатьДокумент1 возвращает ложь и я отменяю транзакцию, то основная транзакция также становится поломанной. И после этого ЗафиксироватьТранзакцию() не отрабатывает с ошибкой "Транзакция не активна", хотя перед ней ТранзакцияАктивна() = истина
---
1С:Предприятие 8 не поддерживает вложенных транзакций. Это значит, что, фактически, поддерживается только один уровень транзакции. То есть не существует возможности отменить действие транзакции некоторого уровня, не отменяя транзакции вышестоящего уровня.
Возможно у вас в СоздатьДокумент(1) есть ВызватьИсключение ...?
---
Что за бред?

```1c
    НачатьТранзакцию();
    Попытка
    СоздатьДокумент1();
    СоздатьДокумент2();
    ////
    СоздатьДокумент9999();
    //
    ЗафиксироватьТранзакцию();
    Исключение
    Если ТранзакцияАктивна() Тогда
    ОтменитьТранзакцию();
    КонецЕсли;
    // Другие действия по отмене дальнейшего проведения
    КонецПопытки;
```
---
Так это то что было изначально, кроме проверки на активную транзакцию, которая всегда возвращает истина в любом состоянии в текущей ситуации.
Не работает так. Если ошибка при проведении документа(остатков не хватило, например) - транзакция ломается. Тоже самое, если ВызватьИсключение в процедуре.
---
https://habr.com/ru/post/419715/
---
Спасибо. Все встало на свои места.