ОШИБКА В ЭТОЙ ТРАНЗАКЦИИ УЖЕ ПРОИЗОШЛИ ОШИБКИ В ПРОГРАММАХ 1 С

2.

Agapov_Stas

Сейчас в теме

( 1
) Clancy08, а конфигурация какая ?)

3.

Clancy08

Сейчас в теме

Комплексная, что это дает? в подписку на события при записи, передаются кривые значения, вопрос по чему? В УПП или Бухгалтерии, подписки на события по другому работают?

4.

Agapov_Stas

Сейчас в теме

В подписке на события в типовом коде после обновления,

Ну вот дает хотя бы то что можно глянуть на конфу которая типовая и попробовать у себя !


Но с Вашим подходом, думаю Вы и сами разберетесь 🙂 Раз ничего не дает – тогда ответ – это частный случай – проявился он только у Вас т.к. если Вы говорите, что до этого все работало (сильно сомневаюсь что обновление затронуло подписки), то разбирайтесь с базой своей

5.

dj_serega

Сейчас в теме

( 4
) Agapov_Stas, Вот у меня повторилось. Найду время разберусь. И если не забуду отпишусь 🙂

Было 1. Потом нажал на “+” и получилось 2.

ОШИБКА В ЭТОЙ ТРАНЗАКЦИИ УЖЕ ПРОИЗОШЛИ ОШИБКИ В ПРОГРАММАХ 1 С

ОШИБКА В ЭТОЙ ТРАНЗАКЦИИ УЖЕ ПРОИЗОШЛИ ОШИБКИ В ПРОГРАММАХ 1 С

6.

Dimon93dimon

Сейчас в теме

  	Идентификатор = Новый УникальныйИдентификатор(ОбъектXDTO. Id);
	Ссылка = Документы[ИмяДокумента]. ПолучитьСсылку(Идентификатор);
	Объект = Ссылка. ПолучитьОбъект();
	Если Объект = Неопределено Тогда
		Объект = Документы[ИмяДокумента]. СоздатьДокумент();
		Объект. УстановитьСсылкуНового(Ссылка);
	КонецЕсли;
  

7.

Kamikadze

Сейчас в теме

У меня такая же проблема. Суть ошибки в том, что происходит проведение документа в трансакции, происходит ошибка при проведении и дальнейшее использование ссылки невозможно.

8.

ВИЛенин

Сейчас в теме

Мне вот интересно почему сей вопрос решает установкой полных прав?

9.

baza1978

Сейчас в теме

тоже напоролся на этот косяк 8.3.6.2076

в подписке при записи документа если меняю чтото в строке тч в цикле

  Для Каждого СтрокаТовары из Товары Цикл
.
КонецЦикла  

в следующей строке цикла на некоторых ссылочных полях строки тч получаем “ошибка получения представления значения” и рантайм еррор поле не обнаружено и т.д.

причем под полными правами все работает.

10.

elizarovs

Сейчас в теме

Аналогичная проблема на платформе 8.3.9.1818.


Поменял платформу на сервере на 8.3.9.1850. Помогло.

11.

Alister

Сейчас в теме

Нашел эту тему – такая же ошибка, платформа 8.3.8.2197, такая же ошибка в подписке при проведении документа, но прикол в том, что ошибка только в одном документе, если проводить ранние документы этого вида, то все нормально, даже если этот документ скопировать, то копия проводится нормально, а вот этот, конкретный, документ ни в какую.(((


p.s. пробовал платформу 8.3.9.2170 – результат аналогичный.


p.p.s. ошибок в базе нет, права полные


Только подбор платформы? )))

12.

Alister

Сейчас в теме

Видимо редкое природное явление.)

13.

AGLux

Сейчас в теме

Аналогичная проблема всплыла в подписке на событие после перехода на 8.3.9.2170. 🙁

14.

dmpolik

Сейчас в теме

У меня та же проблема конфа КА платформа 8.3.9.2033. Решил дополнительными проверками и отладкой кода.

15.

dj_serega

Сейчас в теме

Опять столкнулся с такой ошибкой 🙁 Пытаюсь создать контрагента на 8.3.9.2170.

ОШИБКА В ЭТОЙ ТРАНЗАКЦИИ УЖЕ ПРОИЗОШЛИ ОШИБКИ В ПРОГРАММАХ 1 С

16.

DJ_Codebase

Сейчас в теме

Видимо ошибка в данном случае вызвана еще не завершенной транзакцией. Т.е. был создан объект в данной транзакции, но она еще не была завершена. Пример: открыл транзакцию, создал объект и пытался сделать запись с этой ссылкой до завершения транзакции.

17.

Xershi

Сейчас в теме

В УТ 11.2


При проведении заказа клиента:

  Функция СоздатьКлючАналитики(ПараметрыАналитики)

	МенеджерЗаписи = РегистрыСведений. АналитикаВидовЗапасов. СоздатьМенеджерЗаписи();
	ЗаполнитьЗначенияСвойств(МенеджерЗаписи, ПараметрыАналитики);
	Если ЗначениеЗаполнено(ПараметрыАналитики. Комитент) Тогда
		МенеджерЗаписи. Поставщик = ПараметрыАналитики. Комитент;
	КонецЕсли;
	
	СправочникОбъект = Справочники. ВидыЗапасов. СоздатьЭлемент();
	ЗаполнитьЗначенияСвойств(СправочникОбъект, ПараметрыАналитики);
	СправочникОбъект. Наименование = ПолучитьНаименованиеВидаЗапасов(СправочникОбъект);
	СправочникОбъект. Записать();

	МенеджерЗаписи. КлючАналитики = СправочникОбъект. Ссылка;
	МенеджерЗаписи. Записать(Ложь);

	Возврат СправочникОбъект. Ссылка;

КонецФункции
  

Ошибка на МенеджерЗаписи. Записать(Ложь);


СправочникОбъект. Ссылка = “ошибка получения представления значения”


Платформа 1С:Предприятие 8.3 (8.3.10.2580)


Режим совместимости Версия 8.3.6

18.

Kamikadze

Сейчас в теме

19.

Const1C

Сейчас в теме

Была аналогичная проблема. Решил перезагрузкой компьютера и сбросом кэша 1С.

20.

YalanchidiO

Сейчас в теме

Возникла такая же проблема. Платформа 1С:Предприятие 8.3 (8.3.10.2650). Решила ее, добавив при записи документа оповещение об изменении ссылки:

21.

Samarkan63

Сейчас в теме

22.

jimli

Сейчас в теме

В данной транзакции уже происходили ошибки!

0


Privetanya

Ошибка при вызове метода контекста (Выполнить)


Выборка = Запрос. Выполнить(). Выбрать();


по причине:


Ошибка выполнения запроса


по причине:  


В данной транзакции уже происходили ошибки!

после выполнения


Номенклатура=Справочники. Номенклатура. ПолучитьСсылку(Новый УникальныйИдентификатор(ИдНоменклатуры))


Номенклатура =Ошибка получения представления значения: В данной транзакции уже происходили ошибки!

1


Cyberhawk

В поломанной транзакции обращаться к БД нельзя

2


Cyberhawk

Истинная проблема где-то в коде до того места, где тебе показало эту ошибку

3


piter3

С чего решил,что здесь?


Номенклатура=Справочники. Номенклатура. ПолучитьСсылку(Новый УникальныйИдентификатор(ИдНоменклатуры))

4


Privetanya

после выполнения этой строки номенклатура=Ошибка получения представления значения: В данной транзакции уже происходили ошибки! Отладчиком проверяла

5


Privetanya

как найти?

6


Cyberhawk

Отладчиком тем более нет смысла проверять, т.к. ты все еще внутри поломанной транзакции

7


Cyberhawk

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

8


piter3

9


Privetanya

10


piter3

И че?Ищи,попробуй на копии без транзакции

11


Privetanya


так странно. В этой функции ВИНоменклатуры = Неопределено


Функция НайтиСоздатьНоменклатуру(СтрокаТовара, Знач ВидНоменклатуры, СтавкаНДС, ВИНоменклатуры = Неопределено)

    
    Номенклатура = Справочники. Номенклатура. ПустаяСсылка();


    ВИНоменклатуры = Неопределено;

    
    УспешноНайдено = ВыполнитьПоискНоменклатурыХарактеристикиПоСсылкам(СтрокаТовара, Номенклатура, ВИНоменклатуры= Неопределено);

а при вызове ВыполнитьПоискНоменклатурыХарактеристикиПоСсылкам приходит уже Истина.


Функция ВыполнитьПоискНоменклатурыХарактеристикиПоСсылкам(СтрокаТовара, Номенклатура, ВИНоменклатуры)

    
    Если НЕ ЗначениеЗаполнено(СтрокаТовара. ТоварУслугаИд) Тогда


        Возврат Ложь;


    КонецЕсли;

        
        ИдНоменклатуры = ПолучитьИдНоменклатуры(СтрокаТовара. ТоварУслугаИд);


        Номенклатура = Справочники. Номенклатура. ПолучитьСсылку(Новый УникальныйИдентификатор(ИдНоменклатуры));

12


piter3

Истина это нашла или нет?Я же не вижу что там

13


Privetanya

Если посмотреть в комплексной,то там получает так же неопределено. А у меня истина.

14


piter3


Может стоит подумать над кодом и отличиями?

15


Вафель

в транзакции нельзя записывать с попыткой. все равно ломается

16


Privetanya


Вот ищу отличия

17


dka80

Функция ВыполнитьПоискНоменклатурыХарактеристикиПоСсылкам(СтрокаТовара, Номенклатура, ВИНоменклатуры)


Возврат Истина


КонецФункции

Тогда увидишь где ошибка ранее

18


zva

Вместо УспешноНайдено = ВыполнитьПоискНоменклатурыХарактеристикиПоСсылкам(СтрокаТовара, Номенклатура, ВИНоменклатуры= Неопределено);


нужно УспешноНайдено = ВыполнитьПоискНоменклатурыХарактеристикиПоСсылкам(СтрокаТовара, Номенклатура, ВИНоменклатуры);

19


catena

УспешноНайдено = ВыполнитьПоискНоменклатурыХарактеристикиПоСсылкам(СтрокаТовара, Номенклатура, ВИНоменклатуры= Неопределено);

– ну еще бы оно не приходило “Истина”

20


Privetanya

ошибка осталась

21


Privetanya


не вижу ошибку ранее,значит она в этой функции

22


Privetanya

Функция ВыполнитьПоискНоменклатурыХарактеристикиПоСсылкам(СтрокаТовара, Номенклатура, ХарактеристикаНоменклатуры)

       
        Если НЕ ЗначениеЗаполнено(СтрокаТовара. ТоварУслугаИд) Тогда


                Возврат Ложь;


        КонецЕсли;

               
                ИдНоменклатуры = ПолучитьИдНоменклатуры(СтрокаТовара. ТоварУслугаИд);


                Номенклатура = Справочники. Номенклатура. ПолучитьСсылку(Новый УникальныйИдентификатор(ИдНоменклатуры));


                Если Номенклатура = Справочники. Номенклатура. ПустаяСсылка() Тогда


                        Возврат Ложь;


                КонецЕсли;

               
                Если Номенклатура. ПолучитьОбъект() = Неопределено Тогда


                        // Объект не найден


                        СообщитьПользователю(“Номенклатура не найдена по уникальному идентификатору: ” + ИдНоменклатуры, Ложь);


                        Возврат Ложь;


                КонецЕсли;

               
                Если НЕ Номенклатура. ВестиУчетПоХарактеристикам Тогда


                        Возврат Истина;


                КонецЕсли;

               
                ИдХарактеристики = ПолучитьИдХарактеристики(СтрокаТовара. ТоварУслугаИд);


                Если ПустаяСтрока(ИдХарактеристики) Тогда


                        Возврат Истина;


                КонецЕсли;

               
                ХарактеристикаНоменклатуры = Справочники. ВариантыИсполнения. ПолучитьСсылку(Новый УникальныйИдентификатор(ИдХарактеристики));


                ПустаяХарактеристикаСсылка=Справочники. ВариантыИсполнения. ПустаяСсылка();


                Если ХарактеристикаНоменклатуры = ПустаяХарактеристикаСсылка Тогда


                        Возврат Истина;


                КонецЕсли;

                       
                Если ХарактеристикаНоменклатуры. ПолучитьОбъект() = Неопределено Тогда


                        СообщитьПользователю(“Объект < ХарактеристикаНоменклатуры> не найден: ” + Строка(ИдХарактеристики)


                                + “; Будет создан новый объект.”, Ложь);

23


Вафель

нельзя ЗАПИСЫВАТЬ в попытке. ищи запись выше по коду

24


Cyberhawk


Что-то ты несешь ерунду

25


catena

Поставь уже в отладчике остановку по ошибке.

26


GGDots

27


DrZombi

28


DrZombi

Тут и без отладчика видно ошибку 🙂

29


DrZombi

+ “Если Номенклатура. ПолучитьОбъект() = Неопределено Тогда”

30


Privetanya

похоже поняла. Ошибка происходит при записи договора контрагента.

31


DrWatson

Нужно найти ту первую Попытку с записью данных в БД, которая вываливается в исключение без “В данной транзакции уже происходили ошибки!”. После такого исключения продолжать работу в транзакции уже нельзя. Нужно выходить из всех вызывающих процедур. Лучше всего это сделать через ВызватьИсключение с человеческим сообщением об ошибке или вообще не делать попытку.


Возможно, обработка просто не рассчитана на работу в транзакции.

32


catena

По-моему, проверяется найденность элемента по переданному ИД. А как надо?

33


hhhh

а точно там “Неопределено” выдаст? может null?

34


catena

35


Cyberhawk

Запросом же можно (с условием на ссылку)

36


catena

Ну, это дело вкуса, при разовом обращении не вижу тут грубой ошибки.

37


Cyberhawk

Все зависит от того, планируется ли дальнейшая работа с объектом. Если только для проверки существования, то избыточное получение данных налицо.

Ошибки базы данных и транзакции

При работе с базой данных могут происходить ошибки. В 1С:Предприятии 8 ошибки базы данных подразделяются на следующие две категории:

К невосстановимым относятся такие ошибки базы данных, при возникновении которых функционирование 1С:Предприятия 8 может быть серьезно нарушено. Поэтому, во избежание более серьезных неприятностей (например, порчи данных),  при возникновении невосстановимой ошибки выполнение 1С:Предприятия 8 прекращается. Если невосстановимая ошибка базы данных произошла в процессе выполнения транзакции, то все изменения сделанные в рамках этой транзакции отменяются.

При возникновении восстановимой ошибки считается, что серьезных нарушений в работе 1С:Предприятия 8 не произошло и работа может быть продолжена, но сама вызвавшая ошибку операция прекращается, и вызывается исключение, которое может быть перехвачено и обработано средствами встроенного языка. Казалось бы, все понятно. Но есть тонкость. Если восстановимая ошибка базы данных произошла в процессе выполнения транзакции, то, вне зависимости от того, было исключение, вызванное этой ошибкой, перехвачено и обработано или нет, транзакция уже не может быть продолжена или зафиксирована. Единственная операция с базой данных, которую можно произвести в такой ситуации – это отмена транзакции. Таким образом, приведенный фрагмент кода не вполне корректен:

Копировать в буфер обмена

  НачатьТранзакцию
Записано 
 Записано 
 
 ДанныеЗаписать
 Записано 
 
 

ЗафиксироватьТранзакцию  

Если при выполнении оператора Данные. Записать()
произойдет восстановимая ошибка базы данных (например, по причине того, что элемент данных был заблокирован другим пользователем), то вызванное этой ошибкой исключение будет перехвачено, но повторное выполнение этого же оператора в цикле уже безусловно приведет к ошибке, так как при выполнении данной транзакции уже имела место ошибка базы данных. Следует заметить, что не всякая ошибка приводит к невозможности продолжения выполнения и фиксации транзакции, а именно ошибка базы данных. Исключения, не имеющие отношения к ошибкам базы данных, никакого влияния на возможность продолжения выполнения транзакции не оказывают.

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

Копировать в буфер обмена

  Записано 
 Записано НачатьТранзакцию();
 
 ДанныеЗаписать
 ЗафиксироватьТранзакцию
 Записано 
 
 ОтменитьТранзакцию
 
  

В данном варианте, если при выполнении оператора Данные. Записать()
 произойдет восстановимая ошибка базы данных, то при обработке исключения, вызванного этой ошибкой, транзакция будет отменена и при повторном выполнении цикла транзакция будет начата сначала.

Следует однако сделать предостережение. Дело в том, что в рамках уже выполняемой транзакции можно обращаться к методам НачатьТранзакцию()
, ЗафиксироватьТранзакцию()
и ОтменитьТранзакцию()
. Однако вызов метода НачатьТранзакцию()
при уже выполняющейся транзакции не означает начала новой транзакции. В этом случае просто произойдет увеличение на 1 значения внутреннего счетчика транзакций. Метод НачатьТранзакцию()
начинает новую транзакцию только в том случае, если значение внутреннего счетчика транзакций равно 0. Аналогично, обращение к методам ЗафиксироватьТранзакцию()
или ОтменитьТранзакцию()
приводит к реальному завершению транзакции только в том случае, если значение внутреннего счетчика транзакций равно 1. Если при значении счетчика транзакций большем 1 произойдет обращение к методу ЗафиксироватьТранзакцию()
, то значение счетчика будет просто уменьшено на 1:

Копировать в буфер обмена

  НачатьТранзакцию    // Начало транзакции - счетчик становится равным 1    


НачатьТранзакцию    // Счетчик увеличивается на 1 и становится равным 2    


ЗафиксироватьТранзакцию    // Счетчик уменьшается на 1 и становится равным 1    


ЗафиксироватьТранзакцию    // Фиксация транзакции    
  

Если же при значении счетчика траназкций большем 1 произойдет обращение к методу ОтменитьТранзакцию()
, то значение счетчика транзакций не только будет уменьшено на 1, но и произойдет установка признака, не позволяющего зафиксировать результаты выполнения всей транзакции в целом. И последующее обращение к методу ЗафиксироватьТранзакцию()
, выполняемое при значении счетчика транзакций равном 1, фактически приведет к отмене  транзакции:

Копировать в буфер обмена

  НачатьТранзакцию    // Начало транзакции - счетчик становится равным 1    


НачатьТранзакцию    // Счетчик увеличивается на 1 и становится равным 2    


ОтменитьТранзакцию    // Счетчик уменьшается на 1 и становится равным 1, устанавливается признак отмены транзакции.      


ЗафиксироватьТранзакцию    // Фактическая отмена транзакции    
  

Аналогично, ошибка базы данных, произошедшая при значении счетчика транзакций большем 1, приведет к невозможности продолжения и фиксации всей транзакции в целом.

Таким образом, не всегда можно быть уверенным, что обращение к методу НачатьТранзакцию()
действительно начинает новую транзакцию, а обращение к методам ЗафиксироватьТранзакцию()
и ОтменитьТранзакцию()
означает завершение транзакции в целом. Поэтому, конструкции с циклическим повторением попытки “прорваться через транзакцию” следует применять только в тех случаях, когда есть уверенность, что обращение к методу НачатьТранзакцию()
действительно начинает новую транзакцию. И только при условии, что действительно есть необходимость “прорваться”. Во многих случаях, при возникновении ошибки, разумнее выдать сообщение пользователю и предоставить ему самому решать: повторить попытку выполнения операции еще раз, или перед повторением попытки следует предпринять какие-то действия по разрешению ситуации, приведшей к ошибке.

Программа 1С является самой популярной и наиболее удобной при автоматизации предприятия. В ней предусмотрены решения, созданные на базе одной платформы, соответственно, функционируют они по одному принципу, что значительно упрощает использование ПО. Нередко пользователи сталкиваются с сообщением «В данной транзакции уже происходили ошибки». Рассмотрим как в 1С 8.3 исправить подобную проблему.

1С 8.3 документация по работе с программой

Причина появления сообщения о повторных ошибках в 1С 8

Главная проблема заключается в том, что сообщение об ошибке «В данной транзакции уже происходили ошибки» неинформативно, нет никакой конкретики. Поэтому будем опираться на проблемы, с которыми чаще всего сталкиваются пользователи. Например, с технической стороны ошибка такого рода может возникнуть при первой транзакции, то есть и при первичном обращении к базе данных.

Часть функций, которые выполняет платформа 1С

Подобная ошибка может произойти при обработки ситуации «Попытка-Исключение». Например, при создании записи «Объект_1» формируется исключительная ситуация, а сама ошибка появляется в «Ссылка_2. Наименование». То есть происходит запрос базы данных объектной модели.

В «Попытке-Исключение» начинается обработка операции, которая также должна быть выполнена в транзакции, которая, в свою очередь, может быть явной или неявной (создается в момент записи объекта).

1С: Предприятие 8.3 не поддерживает транзакций вложенного типа. Однако допускается создание вложенной конструкции сразу нескольких транзакций. Из-за наличия явной и неявной транзакции может возникнуть ошибка. То есть программа запрещает транзакцию 1-го уровня на более низших уровнях.

Есть ли смысл исправлять ошибки транзакции, которые уже происходили

При работе с 1С 8.3 не стоит оставлять подобные вещи без внимания. Прежде всего, другой пользователь также может столкнуться с ней, но не поймет причин её возникновения. Если не выполнить отладку системы, то в дальнейшем могут возникнуть дополнительные проблемы. Так как оповещение «В данной транзакции уже происходили ошибки» появляется при первом обращении, то в журнале регистрации данная строка обязательно зафиксируется, но, опять же, без подробного пояснения. Хоть ошибка и располагается на нижнем уровне кода, она нарушит необходимую иерархию. Это приведет к сбою других функций и только еще больше запутает администратора.

При наличие некорректного кода, транзакции будут выполняться с нарушениями или не будут выполняться вовсе. Поэтому при возникновении таких сообщений стоит решить проблему.

Устраняем ошибку транзакции в 1С Предприятие версии 8

В первую очередь стоит очистить кэш базы данных. Сделать это можно вручную. Для этого:

  1. Переходим на диск, на котором расположена база 1С.
  2. Переходим в папку с базой (путь может отличаться, но по умолчанию она установлена в той директории, которая показана на фото ниже). Путь в данным кэша 1С версии 8.3


  3. Удаляем кэш вручную. Удаление кэша вручную


  4. То же самое делаем с кэшем в папке 1с8.2.

Также можно выполнить удаление другим способом:

  1. Создаем на рабочем столе пустой документ. Назовем его «Удаление пользовательского кэша». Создание пустого документа на рабочем столе


  2. Указываем в нем следующую строчу и сохраняем документ в формате .bat.

Указание функции для очистки кэша

После того, как файл преобразуется, его можно запустить и весь пользовательский кэш удалится автоматически. Пробуем снова запустить программу и выполнить операцию. Если не помогло, то лучше всего обратиться к администратору. Также нужно помнить про основные особенности написания кода с использованием транзакций. Это поможет исключить ряд распространенных ошибок.

Также вам будет интересно: Ошибка в 1С 7.7 «Порядок сортировки, установленный для базы данных, отличается от системного».

Особенности написания кода, которые помогут исключить ошибку в транзакциях

Прежде всего нужно опираться на нюансы корректной обработки исключений:

  • Метод «Начать транзакцию» должен быть вынесен за пределы «Попытка-Исключение».
  • Действия, осуществляемые после вызова «Начать транзакцию» должны быть в пределах блока «Попытка». К этом также относится чтение, обработка или блокировка данных.
  • Метод «Зафиксировать транзакцию» необходимо прописывать последним в блоке «Попытка» и до «Исключение».
  • В блоке «Исключение» необходимо сначала обратиться к методу «Отменить транзакцию» и уже потом выполнять прочие действия.
  • Если применяются вложенные транзакции, то в конце «Исключение» не лишним будет добавить оператора «Вызвать исключение».
  • В «Исключения» следует добавить соответствующую запись об ошибке.
  • Если транзакция неявная, то нет никакого смысла переходить к методу «Начать транзакцию». Некоторые также пробуют «обернуть» в явную транзакцию те операции, которые и вовсе не нуждаются в согласовании.

Решить проблему транзакций, в которых происходят ошибки, самостоятельно получается не всегда. Поэтому стоит попробовать выполнить простейшие действия – перезагрузить программу или очистить кэш. К более серьезным манипуляциям в 1С стоит переходить только при уверенности, что вы обладаете достаточным опытом.

Как победить ошибку “В данной транзакции уже происходили ошибки”

0


ildary

Уважаемые специалисты, посоветуйте пожалуйста, как правильно в КА2 исправить появление вот такой ошибки:

Добавленный в КА2 2.4.5.86 документ при проведении делает следующее (документ не мой, делали до меня):

Вызывается процедура в которой происходит запись в РС примерно так:

    
    Попытка


        НаборЗаписей. Записать(Ложь);


    Исключение


        ОбщегоНазначенияКлиентСервер. СообщитьПользователю(“У сотрудника ” + ДанныеФизическогоЛица. ФизическоеЛицо + “уже существует ЛС по зарплатному проекту ” + ДанныеФизическогоЛица. ЗарплатныйПроект);


    КонецПопытки;

При выполнении ОбщегоНазначенияКлиентСервер. СообщитьПользователю() появляется ошибка. Я погуглил и решил отказать от транзакции вообще (т.к. проведение уже вызывает транзакцию) – не помогло. Попробовал делать транзакцию как советует ИТС:

            
            ОтменитьТранзакцию();


            ОбщегоНазначенияКлиентСервер. СообщитьПользователю(“У сотрудника ” + ДанныеФизическогоЛица. ФизическоеЛицо + “уже существует ЛС по зарплатному проекту ” + ДанныеФизическогоЛица. ЗарплатныйПроект);

тоже не помогло.

Увидел в интернете, что корень зла в том, что во всём виновата обработка исключения сделал вот так:

        ЕстьОшибка = Истина;


        Попытка

            
            НаборЗаписей. Записать(Ложь);


            ЕстьОшибка = Ложь;

        
        Если ЕстьОшибка Тогда


            ОбщегоНазначенияКлиентСервер. СообщитьПользователю(“У сотрудника ” + ДанныеФизическогоЛица. ФизическоеЛицо + “уже существует ЛС по зарплатному проекту ” + ДанныеФизическогоЛица. ЗарплатныйПроект);


        КонецЕсли;

тоже не помогло. Сижу, чешу репу. Наверное самое правильное – вообще убрать попытку, но тогда как ловить ошибку записи в РС?

1


laeg

Ловить ошибку программно, написать запрос с проверкой на существование данных записей.

2


H A D G E H O G s

ЕстьОшибка = Истина;


        Попытка

Если ЕстьОшибка Тогда


            ОбщегоНазначенияКлиентСервер. СообщитьПользователю(“У сотрудника ” + ПредставлениеСотрудника + “уже существует ЛС по зарплатному проекту ” + ПредставлениеЗарплатныйПроект);


        КонецЕсли;

3


youalex

(0) немного не в тему.

>>при проведении // 1-я транзакция

Вот интересно, учитывая что во вложенные транзакции 1С не умеет, какую транзакцию фиксирует вот этот код:


НаборЗаписей. Записать(Ложь);


ЗафиксироватьТранзакцию();

По идее,  нужно в процедуре объявлять переменную ТранзакцияАктивна = ТранзакцияАктивна() и фиксировать/отменять с условием по ней.

4


mexanik_96

баги нужно исправлять, а не гасить ексепшены. писать код в попытке(в контексте 1с) говорит о не уверенности что код будет работать

5


ildary

в этом месте всегда будет транзакция – т.к эта процедура вызывается только из проведения.


я вообще не понимаю, зачем надо было так делать, но не могу связаться с разработчиком и вынужден придумывать сам.

6


mexanik_96

дак у тебя несколько одинаковых записей пытается записать

7


mexanik_96

+ нужно либо добавить уникальности, либо потрассировать код и посмотреть почему откуда и зачем одинаковые записи приходят

8


ildary

идея интересная, но в наборе только 1 запись – проверил в отладчике. Может ли быть проблема, если при этом одно из измерений – пустое? При этом в его свойствах нет требования заполненности.

9


Eiffil123

Проблем в этом нет. Просто вложенная транзакция не открывается.

10


Малыш Джон

(0) что такое ДанныеФизическогоЛица? ссылка?


тогда конечно будет ошибка, ты после генерации исключения пытаешься разыменовать ссылку.

11


youalex

да, получается, каждое НачатьТранзакцию() увеличивает счетчик транзакций на 1, а ЗафиксироватьТранзакцию() – уменьшает на 1, и реальная фиксация происходит когда счетчик = 1. Отбой, короче)

12


Малыш Джон

именно так

13


Вафель

при проведении никак нельзя записывать с ошибкой, а потом что-то делать еще

14


Cyberhawk

Сколько платят за решение вопроса?

15


Вафель

уже решили же

16


palsergeich

17


ildary

если я правильно понял, то вложенные транзакции лучше не делать вообще. Для случая в (0) – я её (транзакцию) убрал и сделал вместо НаборЗаписей. Записать(Ложь) так: сначала проверяю – есть запись или нет, и если есть, то делаю НаборЗаписей. Записать(Истина)

18


vi0

делай вложенные транзакции скок хошь


главное грамотно всё делай

19


vi0

20


1Сергей

+1


Описания исключений сделай внятные

21


lamina

попробуй после исключение, следующей строкой добавить:


Пока ТранзакцияАктивна() Цикл


  ОтменитьТранзакцию();


КонецЦикла;

22


palsergeich

И вот тут большой костыль)


Транзакция уже в откате из-за ошибки. А транзакция активна вернет ИСТИНА.


Это мега грабли.

23


palsergeich

Вопрос из билета 1сЭксперт


Вопрос 2

Код конфигурации содержит следующий фрагмент:

Какие действия будут отменены в результате выполнения функции ОтменитьТранзакцию() в 7 строке.


Ответ на вопрос 2:

Так как система 1С предприятия не учитывает вложенность транзакций, метод «ОтменитьТранзакцию» отменит все транзакции.


и этот код вернет: Ошибка использования транзакции – Транзакция не активна

24


palsergeich


Но особенность реализации: то что НачатьТранзакцию() и ТранзакцияАктивна() – это всего лишь работа со значениями некого счетчика транзакций, а не реальное состояние транзакции.

25


palsergeich

У меня так один обмен изза такой штуки пару дней выполнялся без ошибок, но никаких данных в БД не было, а все потому что в один справочник в событие ПриЗаписи человек воткнул Попытка Исключение. А это была последняя строчка в коде -> больше никаких операций с БД не было, соответственно пресловутого В данной транзакции уже происходили ошибки тоже. Просто тихий RollBack. Регламентное УСПЕШНО завершалось, никаких диагностических или других каких либо сообщений не было. Просто тупо не писались данные.

26


mexanik_96

зачем вообще писать как в

27


Cyberhawk


Из ответа на этот вопрос с экзамена ты неправильный вывод сделал. Конечно же отменять транзакции надо столько же раз, сколько раз их было начато.

28


palsergeich


Когда ты в транзакции создаешь элемент справочника – неявно такая структура вызовов и происходит

29


Cyberhawk


Это утрированный пример. На самом деле транзакции внутри вложенных процедур могут располагаться. Главное при любом исключении не забывать не только отменять транзакцию, но и вызывать исключение (передавать выше по стеку вызовов), чтобы оно там выше тоже не пыталось зафиксироваться

30


mexanik_96

зачем использовать попытки в контексте 1с? чтобы что? не раз приходилось код как в , дак нет он в продакшене вполне себе ходит

31


palsergeich

А если транзакция уже отменена платформой? Но счетчик в +?

32


palsergeich

Некоторые не заморачиваются

33


mexanik_96

+ еще сверху попытка и пустое исключение.

34


Cyberhawk

Оно в любом случае все будет отменено, что в этот пирог попало, но _не при первом минусовании счетчика_

35


palsergeich

я не делал никаких выводов, я знаю как правильно.


Но поправлять такое приходится за другими постоянно.

36


Cyberhawk

Пустое исключение – это у кого писюны вместо пальцев )


Ну в общем случае так, ибо иногда без нескольких вложенных попыток слишком емко получается.

37


Cyberhawk

А почему на наезжаешь? Из-за нарушения парности “плюс” и “минус”?

38


palsergeich

Потому что ТранзакцияАктивна() нельзя верить

39


mexanik_96

писюны не то слово, ну да ладно

40


palsergeich

Ибо если в своем коде ты уверен что там четко, то то что ошибок, допущенных другими людьми там нет – нет.

41


Cyberhawk

Ну она же возвращает “положительность” счетчика. Почему нельзя верить? Никто вроде и не рассчитывает что этот метод говорит о том, будет ли она успешной

42


palsergeich

Потому что при

ты получишь: Исключительная ситуация — Транзакция не активна.

43


palsergeich

А я вот никому не доверяю, ибо случаи были)

44


Cyberhawk

Это получит тот кто выше по стеку попытается зафиксировать/откатить, когда счетчик уже выведен в ноль кодом товарища из – Я в этом только косяк вижу того цикла.

45


palsergeich

46


Dzenn


Разбирайся с транзакциями и убирай лишние вложенные

47

palsergeich


Я просто год назад наткнулся на то, что это работало не совсем так как должно, кейс уже не помню, но горело знатно.

По этому я больше не верю ТранзакцияАктивна() )

48


palsergeich


Попробовал воспроизвести – сейчас все работает как надо.

Возможно была какая то ошибка платформы.

49


lamina

друзья, но ведь мы уже в исключении, не имеет уже значения сколько было тразнакций до нас, и сколько выкинуто других исключений, ничего уже зафиксировать не получится, поэтому если нам нужно гарантировано в коде продолжить успешное выполнение операции – нужно всё откатить, и если нужно – опять начать транзакцию заново. Да, есть стандарт 1с, который гласит – заворачивайте всё всё в попытку с откатом, но если раззуть глаза – то становится понятно, это хорошо до тех пор, пока кто-то забыл так сделать и вот тогда – опять “ошибки в транзакции”

50


palsergeich

+1. И полностью согласен.


Но я точно помню что этот кусок кода не работал как надо((( Возможно я не очень везучий(


Пока ТранзакцияАктивна() Цикл


  ОтменитьТранзакцию();


КонецЦикла;

51


nicxxx

(0) для начала читаем здесь:


https://habr.com/post/419715/


а в продолжение – реализуем корректную обработку на всех уровнях вложенности транзакций

52


Cyberhawk

Отменять в цикле все уровни вложенности можно только если ты уверен, что выше по стеку код не пойдет, в том числе и через год, когда метод, вызвавший ошибку, обрататываемую твоим кодом, не попытается вызвать кто-нибудь другой, кто тоже обернет свой вызов в транзакцию.


Походу защититься от такого “цикличного опустошения” на более верхнем уровне можно, если перед парной “отменой” проверять, активна ли транзакция.

53


lamina

54


vi0

“пока кто-то забыл так сделать”


кто-то это кто?

55


vi0

“даже если код по стеку и пойдет, это уже бесполезно, ни одна транзакция не будет зафиксирована”


По стеку не обязательно нужно идти чтобы зафиксировать транзакцию.

56


Cyberhawk

Парность надо соблюсти чтобы тот код, что по стеку выше и соблюдающий парность, не споткнулся из-за того, что ты всю парность убил в предлагаемом цикле. Хз с чего ты взял о каком-то успешном завершении транзакции.

57


lamina

58


vi0



> пока не размотаем транзакции, ничего более сделать не получится.


Стандарт не предлагает здесь и сейчас размотать транзакции и продолжить работу, а предлагает эскалировать исключение на верхние вызовы путем выполнения ВызватьИсключение. Т.к. часть записей в БД на верних вызовах уже не будет закомичена, и эти верхние уровни должны об этом знать.

> Давайте пример кода и хватит демагогии


Примера кода есть в типовых, в частности я привел в


А вот что предлагаешь ты разматывая транзакции здесь и сейчас и продолжая работу?

59


lamina

“Стандарт не предлагает здесь и сейчас размотать транзакции и продолжить работу”

И я этого про стандарт не говорил, читай внимательно: “предлагает там, где есть начать/зафиксировать используйте попытку, чтобы сделать откат”. А выброс исключения – это уже дело здравой логики, суть стандарта не в том, чтобы выбросить исключение, а чтобы его перехватить с откатом.

“А вот что предлагаешь ты разматывая транзакции здесь и сейчас и продолжая работу?”


Я утверждаю, что все белиберда с п.3.6. Почему?


1) Да потому что достаточно в 1 из 100500 мест не сделать так, как велит стандарт (коих тьма тьмущая в типовых), и мы получаем проблему, с которой начался этот топик.


2) Никого не смущает, что в попытку нужно завернуть порядочное количество кода, что уже противоречит другому стандарту? И не завернуть его нельзя, по стандарту 3.6


Ну и самое главное, снова повторю, единственно правильным считаю класть в попытку не все подряд, что начинается с НачатьТранзакцию (твой 3.6 так говорит), а использовать попытку только там, где это нужно с точки зрения прикладной задачи, а в исключении этой попытки – не надеяться, что все другие начать/отменить/зафиксировать были сделаны в порядке вызовов, а самому всё откатить и продолжить работу, начав новую транзакцию или что там по задаче требуется. И не нужно думать ни о какой парности при возникновении ислючения, что за параноя на этот счет, если в 999999ой НачатьТранзакцию выбросилось исключение, вы уже никакими ОткатитьТранзакцию/ЗафиксироватьТранзакцию данные не сохраните в 999998 и т.д. транзакции.

“Примера кода есть в типовых, в частности я привел в ”


Вроде не тебе задавал вопрос, но если ты внимательно посмотришь на типовые, то 3.6 там применяется совсем не чаще чем не применятся. Другими словами, от такого совета ТС ни холодно ни жарко.


А если есть претензии к подходу, ответь кодом, а не очередными рассуждениями со ссылками. Пока я вижу что все советы ТС заключаются в том, чтобы он проанализировал 100500 вызовов НачатьТранзакцию типовой конфы и завернул их в 3.6

60


Darych

61


vi0

Так ты приведи свой код, а не очередные рассуждения.

62


vi0

Это к

63


Cyberhawk


“У вас есть код, который начинает транзакцию и фиксирует ее, парность сохранена, все счастливы? Далее” // Конечно же неправильно. У меня есть код, который фиксацию транзакции и значимую часть оной делает внутри попытки, а откат – в искючении.

64


Cyberhawk

Я так понял ты топишь за то, что не поможет там, где исключение возникло в подчиненных методах и не было проброшено назад

65


Сияющий в темноте

Вызывать исключения наверх тоже не всегда хорошо-в 1с нет возможности указания возврата исключений функцией.


Возвращать нужно код ошибки,чтобы при использовании функции в программе было ясно,где и какая ошибка произошла,а не плодить лишние Попытка-Исключение

66


xaozai

(0) Проблема в том, что слишком часто используется Попытка Исключение КонецПопытки;


В большинстве случаев проверки на корректность и т.п. можно и нужно делать другими способами.


А Попытку-Исключение можно использовать в тех случаях, когда выполняются какие-то действия, где проверку средствами платформы проблематично сделать. Например, при записи/чтении файла, когда нет уверенности в наличие прав, или при создании COM-объекта и т.п.

67


Сияющий в темноте

Проблема в том,что даже запись обьекта в базе бросает исключение,хотя можно было бы возвращать код ошибки.

68


vi0

так будет пример кода с разматыванием транзакций, например, для такого случая:

1 НачатьТранзакцию()


2 Объект1. Записать()


3    НачатьТранзакцию()


5    Объект2. Записать()


4    Объект3. Записать() – случилась ошибка при записи

Как нужно поступить после строки 4?

69


Cyberhawk

Один раз вызвать исключение

70


lamina

в твоем примере нет перехвата исключения, поэтому ошибки “в этой транзакции уже были ошибки” не будет, поэтому вопрос я не понял.


Но попробую. Какую проблему мы обсуждаем? Мы обсуждаем вот что: как правильно перехватывать ошибки любого рода, хоть деление на 0, которые происходят в транзакции. Верно?


То есть мы говорим не о НачатьТранзакцию в принципе, а тех, совершенно конкретных участках кода, где нам очень-очень нужно что-то обрабатывать (в цикле проводить доки, например) и делать это в транзакции. Так? Не знаю как тебе, но я говорю именно о таких случаях. Ну и вот, в этих участках кода, на следующей строке после “Попытка” мы запускаем какой-то код, который понаоткрывает транзакций, и который в общем случае их за собой не закроет (и не должен!). И в этом конкретном участке кода, следующей строкой по “Исключение”, учитывая тот факт, что транзакции вложенными быть не могут, нужно отмотать все, и заново начать транзакцию, если это что-то в цикле, или отменить, в зависимости от задачи.


Возвращаясь к вопросу “Как нужно поступить после строки 4?” – никак, будет исключение, все отменится и все будет хорошо.

А теперь вишинка: если мы четвертую строку обернем в попытку и там будет исключение, то что бы мы не делали, Обеъект2. Записать () – в базе не появится! При том, что метод ЗафиксироватьТранзакцию () в какой-нибудь 5 или 6 строке отработает. Поэтому я в очередной раз утверждаю, что цикл размотки транзакций (см. 21) самый практичный подход.

71


youalex

После строки 4 уже никак не поступить. Ибо выполнение кода прервано по ошибке. ЗафиксироватьТранзакцию() не сыграло

72


vi0

> Мы обсуждаем вот что: как правильно перехватывать ошибки любого рода, хоть деление на 0, которые происходят в транзакции. Верно?


Нет не верно. Перехват деления на ноль не будет провоцировать ошибку “В транзакции уже происходили.” и можно будет зафиксировать транзакцию.

не понятны твои рассуждения что код не должен закрывать свои транзакции

и причем здесь проведение документов в цикле? не вижу, что об этом был разговор

ты так и не привел пример программного кода


покажи кодом что ты будешь делать в примере

73


Cyberhawk

Я понял автора

– он про случаи, когда надо “и рыбку съесть, и костями не подавиться” 🙂 Т.е. когда идет пакетная транзакция и из-за ошибки записи одного из объектов не хочется отлуп всем остальным в пакете делать.

74


vde69

если код не в глобальной транзакции то делать надо так

    Исключение


если транзакцияактивна() тогда отменитьтранзакцию() конецесли;


        ОбщегоНазначенияКлиентСервер. СообщитьПользователю(“У сотрудника ” + ДанныеФизическогоЛица. ФизическоеЛицо + “уже существует ЛС по зарплатному проекту ” + ДанныеФизическогоЛица. ЗарплатныйПроект);


    КонецПопытки;

75


vi0

> и костями не подавиться


это в лучшем случае

76


vi0

> Вызывать исключения наверх тоже не всегда хорошо


кстати не обязательно вызывать исключение


можно просто протаскивать флаг ошибки через функции


тот же пресловутый “Отказ”

77


Остап Сулейманович

78


Остап Сулейманович

+ В “классике” ошибка должна быть обработана на том уровне, где она возникла. А на верх должен передаваться результат выполнения.

79


vi0

а если ошибка критичная, которая прервала транзакцию?

80


Рэйв

81


Остап Сулейманович

Я конечно понимаю, что у 1С свое понятие об инкапсуляции. Но все же. Вызывая функцию из вашей библиотеки я не должен знать что и как у вас там внутри устроено. Я должен знать только за успешное/не успешное выполнение. Описалово проблемы в случае неуспешного вызова вложенной функции должно идти бонусом. И все исключения вложенного уровня должны быть там же и обработаны. Поскольку в общем случае я могу и не знать как обрабатывать ваши исключения.

82


Рэйв

>>что у 1С свое понятие об инкапсуляции

Поподробнее об инкапсуляции в 1с можно?:)

83


Рэйв

Жаль конечно, но 1С тебе ничего не должна:-)

84


Рэйв

85


Остап Сулейманович

86


Рэйв

ХА. Три раза

87


Остап Сулейманович

88


Рэйв

Это хрень, которую интерфейсами 1С дает :


-))

89


Остап Сулейманович

90


Рэйв

Это точно не инкапсуляция:-)

91


Остап Сулейманович

92


Рэйв

93


Рэйв

94

Рэйв

И в этот класс инкапсулировать свои процедуры

95


Рэйв

96

Рэйв

97

Остап Сулейманович

“если я могу сделать свой класс.”

А если ты пользуешься чужими классами с закрытой реализацией то это что?

98


Рэйв


Чужая реализация – это чужие команды. Учить можно но не очень приятно

99


Остап Сулейманович

“И в этот класс инкапсулировать свои процедуры”

100


Рэйв

ну ка дай определение Полиморфизм?

101


Остап Сулейманович

102


Рэйв

103


Остап Сулейманович

Поищи в своих интернетах. Там должно было быть.

104


Рэйв

конечно должно быть. я и так знаю.


Только ты нуб в программировании и не надо тут из себя строить

105


Darych

106


Рэйв

107


Рэйв

У него в программинге вообще пипски нет.

108


Остап Сулейманович

109


Рэйв

Я даже знаю что такое инкапсуляция. Но тебе не скажу. Сам учись:-)

110


Остап Сулейманович

Когда для объекта ДокументDOM выкатишь реализацию метода ВставитьПеред() – продолжим. А пока (с учетом ) – ты то что прописано в .

111


Рэйв

>>реализацию метода ВставитьПеред()


Это как раз наследование:-)

112


Рэйв

113


Остап Сулейманович

114


Рэйв

>> Реализация = наследование


Да запросто.

115


Рэйв

Мне интересны твои доводы против:-)

116


Остап Сулейманович

Я уже не удивляюсь.

117


Рэйв

Естественно. Ты идешь паситсь:-))

118


Рэйв

Пастись и есть траву:-))

119


Остап Сулейманович

А кроме хамства еще какие-нибудь аргументы есть?

120


Рэйв

У меня тоесть. А у тебя нет.

121


vi0

кто пустил детей в интернеты

122


Рэйв

Они там живут(дети),сволочи.

123


lamina

Ты пишешь: “если код не в глобальной транзакции то делать надо так”. Можно получить объяснения, зачем? Не словами, а примером кода, который не будет работать, если это правило не соблюсти.

Все что я смог по этому поводу, уже написал, повторяю: пример кода был в 21, а твой случай 68 – ничего там делать не нужно, поэтому примера кода нет.

124


Конструктор1С


Учись юзать ВызватьИсключение

125

vde69


понимаешь в чем дело, в 1с нет стека транзакций и флаг отката транзакции он глобальный, то есть без разнице на каком уровне произошла ошибка ты не сможешь откатить или зафиксировать одну транзакию внутри другой.


теперь объясняю почему 74 правильно:

запись документа – это не явная транзакция и если в ней происходит ошибка то она взводит глобальный флаг ошибкитранзакции, и по этому если в ней произошла ошибка надо явным образом откатить транзакцию верхнего уровня,  или вообще не надо делать верхнюю транзакцию

126


vi0


кстати, кто там говорил что в типовых не ипользуется эскалация исключения (ВызватьИсключение;)

посмотрите ут11 – на каждом шагу

127


Остап Сулейманович

Всему должно быть место и время.

То, что исключение должно быть обработано на своем уровне изоляции – это да.

Но вот такой пример. Из моей практики. Обращение к ВЕБ-Сервису с передачей некорректных параметров. Теоретически возможно проанализировать параметры, обработать и вернуть допустим код ошибки. Вроде все правильно. Н О. В таком варианте ошибка самого ВЕБ-сервиса будет неотличима от ошибки на вызывающей стороне. Потому в модуле ВЕБ-сервиса вызывается такая вот фигня :


ВызватьИсключение “Трам пам пам”;

И тогда ошибка вызывающей стороны диагностированная в ВЕБ-сервиса вызовет исключение не у себя в модуле, а передаст выше по стеку вызовов.

128


Остап Сулейманович

+ (127) А по поводу транзакций – вот здесь https://its.1c.ru/db/metod8dev#content:2313:hdoc
все от “создателя”.

129


vi0

(128) тут вопросов нет

130


vi0

(127) чет не понял, что ты сказать хотел

131


Остап Сулейманович

(130) Насчет кидать исключения наверх или нет.


1. Стараться не кидать.


2. Смотреть по обстоятельствам.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *