Имя: Пароль:
1C
 
Вопрос по транзакциям
0 Wefast
 
03.06.22
18:53
Делаю загрузку с файла

Создаю в цикле элемент справочника.
Добавляю созданный элемент в таб часть документа ввода остатков.
После цикла записываю.

В таблице бывают некорректные данные из-за чего элемент справочника не записывается.

Мне нужно чтобы такой элемент не создавался.
Но если документ при этом не сможет записаться, чтобы и элементы справочника тоже не создавались.

Вычитал тут что можно делать так:

НачатьТранзакцию()
ЕстьОшибка = ЛОЖЬ;

Попытка
    //    
Исключение
    ЕстьОшибка = ИСТИНА;
    Сообщить(ОписаниеОшибки();
КонецПопытки  

Попытка
    
Исключение
    ЕстьОшибка = ИСТИНА;
    Сообщить(ОписаниеОшибки();
КонецПопытки


Если НЕ ЕстьОшибка Тогда
    ЗафиксироватьТранзацию();
ИНаче
    ОтменитьТранзацию();
КонецЕсли;

////////////////////////////////////

Написал такое:

НачатьТранзакцию();
    //Попытка
            // Тут получаю таблицу Таб    
    ДокВВ = Документы.ВводНачальныхОстатков.СоздатьДокумент();
    Отказ = ЛОЖЬ;
    
    Для  Каждого Стр из Таб Цикл
        Попытка    
            Партия = Справочники.ПартииНоменклатуры.СоздатьЭлемент();
            
            // заполняю тут элемент справочника

        Исключение        
                /// ЕСЛИ при заполнение ошибка то сейчас хочу все прервать, т.к. при заполнение ничего не создается и идет только поиск
            Сообщить(ОписаниеОшибки());
            ОтменитьТранзакцию();
            Возврат;
        
        КонецПопытки;
        
        Попытка
            Партия.Записать();
        ИСключение
                // Если элемент не записался, сообщаю почему и иду дальше
            Сообщить(ОписаниеОшибки());
            Продолжить;
        КонецПопытки;
        
        Если МоеУсловие Тогда
            НС = ДокВВ.Запасы.Добавить();
                // Заполняю строку
        КонецЕсли;
    КонецЦикла;                
        
    Если ДокВВ.Запасы.Количество() > 0 Тогда
        ДокВВ.Организация         = Справочники.Организации.ОрганизацияПоУмолчанию();
        
        Попытка
            ДокВВ.Записать();
        Исключение
            Сообщить(ОписаниеОшибки());
            Отказ = ИСТИНА;
        КонецПопытки;
    КонецЕсли;

    Если Отказ Тогда
        ОтменитьТранзакцию();
        Сообщить("Транзакция отменена");
    Иначе
        
        ЗафиксироватьТранзакцию();
    КонецЕсли;



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


В общем, как вообще подобное делают?
Сейчас я знаю что партия не записывается из-за того что код не уникальный. В принципе я могу искать по коду партию, тем самым проверять есть такой элемент или нет.
Ну и в принципе каждый раз делать проверку на все частные случаи.
Но таблица большая и лишние подобные поиски думаю заметно увеличат загрузку.
1 Йохохо
 
03.06.22
19:00
получается, если номенклатура создана вся, можно создавать документ, мистер фикс
2 youalex
 
03.06.22
19:16
Транзакцию надо откатывать после первого же исключения (если исключение невосстановимое, при записи в БД например), и сразу
(https://its.1c.ru/db/v8std/content/783/hdoc)
Иначе при повторном обращении к БД будет собственно эта ошибка "в данной транзакции были уже ошибки"

Как вариант, можно твой код вынести в отдельную функцию (убрать там попытки, если тебе не нужно различать исключения, и транзакции)
, и в Попытке делать вызов этой функции, типа

НачатьТранзакцию();
Попытка
  СоздатьДокументЧегоТоТам();
  ЗафиксироватьТранзакцию();
Исключение
  ОтменитьТранзакцию();
  Сообщить(ОписаниеОшибки());
КонецПопытки;
3 Мультук
 
гуру
03.06.22
20:04
4 TormozIT
 
гуру
03.06.22
22:29
2 + 2 = 3.9999999999999999999999999999999...