Вход | Регистрация
 
1С:Предприятие :: 1С:Предприятие 8 общая

Исключение при выполнении ДокументСсылка.ПолучитьОбъект(). Фоновые задания.

Исключение при выполнении ДокументСсылка.ПолучитьОбъект(). Фоновые задания.
Я
   Морфиус
 
03.03.20 - 16:42
Есть такой код, выполняемый в конкуренции фоновых заданий на сервере (8.3.15 в разных релизах) - одна функция, вызываемая из разных фоновых заданий.

Запрос = Новый Запрос("ВЫБРАТЬ ПЕРВЫЕ 1
            |    Заявка.Ссылка
            |ИЗ
            |    Документ.Заявка КАК Заявка
            |ГДЕ
            |    Заявка.ПользовательСайта = &ПользовательСайта            
            |    И НЕ Заявка.ПометкаУдаления ");
            Запрос.УстановитьПараметр("ПользовательСайта",ПользовательЗаявки.Ссылка);

            Выборка = Запрос.Выполнить().Выбрать();
            Если Выборка.Следующий() Тогда
                Попытка
                    Док = Выборка.Ссылка.ПолучитьОбъект();
                Исключение
                    ЗаписьЖурналаРегистрации(" Не удалось ПолучитьОбъект() Док.Заявка",УровеньЖурналаРегистрации.Ошибка,,,
                                        "Дамп
                    | Заявка УИД : " + СокрЛП(Выборка.Ссылка.УникальныйИдентификатор()) +"
                    | Заявка : " + СокрЛП(Выборка.Ссылка) +"
                    | Размер выборки : " + Выборка.Количество() + "  
                    | Блокирован ? : нельзя проверить, так как не создан документ.");
                    
                КонецПопытки;




// Далее по причине конкуренции, ставим блокировку на объект.
                БлокировкаДанных = Новый БлокировкаДанных;
                  ЭлементБлокировки = БлокировкаДанных.Добавить("Документ.Заявка");
                ЭлементБлокировки.УстановитьЗначение("Ссылка", Док.Ссылка);
                ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;
                БлокировкаДанных.Заблокировать();
                                Возврат Док;
                  КонецЕсли;


Проблема:
    Иногда, примерно раз в две недели, ДокументСсылка.ПолучитьОбъект() сваливается в исключение. Текст Ошибки: ОбщийМодуль.ОбменЗаявками.Модуль(2073): Ошибка при вызове метода контекста (ПолучитьОбъект)

    Согласно 1С документации: ДокументСсылка.ПолучитьОбъект() не генерирует исключение.

    Удалось выяснить что ссылка живая СокрЛП(Выборка.Ссылка.УникальныйИдентификатор())   - 45a41c5f-5d28-11ea-baec-00155d2b2d03
    Представление документа также считалось из БД СокрЛП(Выборка.Ссылка): Заявка 0000036 от 03.03.2020 11:23:34
    Дата создания документа на 30 минут раньше времени исключения, т.е. документ присутствует в БД.

Как обойти ошибку? Ставить таймаут на несколько секунд и повторять снова? Какие идеи?
 
 
   vicof
 
1 - 03.03.20 - 16:45
А зачем получать объект в этой процедуре?
   ДенисЧ
 
2 - 03.03.20 - 16:45
Нужно смотреть в модуль объекта
   fisher
 
3 - 03.03.20 - 16:49
Добавь в запись ЖР исходное ОписаниеОшибки() и не морочь голову. С большой вероятностью при следующем падении ты уже будешь знать ошибку.
   fisher
 
4 - 03.03.20 - 16:56
Варианты навскидку:
- ошибка в секции инициализации модуля объекта
- падение по таймауту, если данные объекта заблокированы в СУБД (исключительные блокировки СУБД). Но в версионнике такого по идее в режиме управляемых блокировок быть не должно.
   Морфиус
 
5 - 03.03.20 - 16:57
ОписаниеОшибки() было в предыдущей версии и оно на экране: Ошибка при вызове метода контекста (ПолучитьОбъект) 

В модуле объекта кроме ОбработкаПроведения() нет функций/процедур обработки событий объекта, или переменных. Для этого документа нет ПодписокНаСобытия. Кроме того, В ОписаниеОшибки стек глубже не раскручивается, Только "Ошибка при вызове метода контекста (ПолучитьОбъект)".
   fisher
 
6 - 03.03.20 - 16:58
(5) Какая СУБД? Какой режим блокировок в конфигурации?
   Морфиус
 
7 - 03.03.20 - 17:00
Режим управления блокировкой данных: Управляемый. Режим совместимости: 8.3.8 (Старенькая конфигурация)
   fisher
 
8 - 03.03.20 - 17:02
СУБД какая? Важно понять, в каком она у тебя работает режиме. Версионника или блокировочника. Т.е. если mssql - используется ли режим снэпшотов.
   Морфиус
 
9 - 03.03.20 - 17:02
СУБД - Скорее всего MS - Mycrosoft SQL Server (это у клиента). На Linux Postgress ошибки не наблюдал, но статистики мало.
   Сияющий в темноте
 
10 - 03.03.20 - 17:02
кстати,если в модуле документа кинуть исключение,то оно прилетит в код получения обьекта по ссылке,что достаточно логично.
так что сама процедура исключений не генерит,но этого нельзя сказать про код модуля.
   fisher
 
11 - 03.03.20 - 17:10
(9) Если старый mssql который работает в режиме блокировочника с 1С, то гипотетически могу предположить попадание ПолучитьОбъект() как раз на блокировку при попытке изменения данных документа в конкурирующем процессе. А почему, кстати, ты сначала объект получаешь а потом блокировку накладываешь? Почему не наоборот?
   Морфиус
 
12 - 03.03.20 - 17:13
>> Важно понять, в каком она у тебя работает режиме. Версионника или блокировочника. Т.е. если mssql - используется ли режим снэпшотов.
Понятно что проблемы с СУБД. Только это из плоскости, что нельзя изменить. Программа разрабатывается и тестируется на разных платформах. 1С-ка НЕ должна исключение выбрасывать. И еще раз - Представление из БД считалось, А блокировка объекта проверяется после создания объекта.

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

Не совсем понял. Я конечно попробую версию модуля документа.... Но там ничего нет. Может откомпилировать не может, какие-то функции в фоновом под запретом? Но это мысли себе на заметку.

>> А почему, кстати, ты сначала объект получаешь а потом блокировку накладываешь?
Что бы исключить блокировку себя с собой "для чистоты эксперимента"
   Морфиус
 
13 - 03.03.20 - 17:24
Конкуренция может быть любая. Если объект заблокирован - это нормально, даже на производительность не влияет. Должен быть инструмент разрешения блокировки. Я попробую снять поставить таймаут, и посмотреть, будет ли создаваться объект. Идею с ошибкой в модуле документа считаю маловероятной - две недели между исключениями интенсивной нагрузки все работает ...
   fisher
 
14 - 03.03.20 - 17:38
Я не исключаю, что "сваливаться" получение объекта может как раз по причине попадания на исключительную управляемую блокировку. Но не уверен. В принципе, это легко можно проверить.
Если тебе нужен механизм очереди обработки документов конкурирующими процессами, то как вариант вместо управляемой блокировки можно использовать объектную блокировку (метод Заблокировать()) не боясь, что будет конфликт с другими видами блокировок.
   pechkin
 
15 - 03.03.20 - 17:51
нужно сначала делать блокировку (в транзакции), а потом получать и изменять.
иначе помимо невозможности получить можно словить: объект был изменен
   pechkin
 
16 - 03.03.20 - 17:53
ну и собственоо в 1с нет блокирующей очереди. поэтому твой код не очень оптимальный.
лучше иметь 1 управляющее задение, которое будет читать по н штук и запускать н потоков для орбработки
   Морфиус
 
17 - 04.03.20 - 09:06
(16) Вы рассуждаете, ничего не зная о другом коде.

Еще раз, прошу обратить внимание : НЕТ ПРОБЛЕМ С БЛОКИРОВКАМИ. ЕСТЬ ПРОБЛЕМА НЕДОКУМЕНТИРОВАННОГО ПОВЕДЕНИЯ 1с.

Согласно документации, наличие блокировки можно проверить либо ДокументОбъект.Заблокирован() - для "своей" блокировки.
или через исключение
Попытка
    ДокументОбъект.Заблокировать();    
Исключение КонецПопытки;

Очевидно, что и

Попытка
    НовДокумент.Записать(РежимЗаписиДокумента.***);
Исключение КонецПопытки;

Не уверен, поправьте если не прав, но ДокументСсылка.ПолучитьОбъект() не может быть связан с механизмом блокировок, только по той причине, что ДокументСсылка.ПолучитьОбъект() можно вызывать многократно, даже если объект заблокирован - это НОРМАЛЬНО, и это всегда и везде работает.
   Морфиус
 
18 - 04.03.20 - 10:29
ДокументСсылка.ПолучитьОбъект(), согласно документации может вернуть НЕОПРЕДЕЛЕНО, и так проверяют битые ссылки. Но не свалится в исключение.
   Ёпрст
 
19 - 04.03.20 - 10:35
(18) есть шанец, что  Выборка.Ссылка = Неопределено или null ? Хз, что там за запрос у вас, тем более вы ОписаниеОшибки() не пишите в лог.
Мот там банально не ссылка на док вот и сваливается с ошибкой при ПолучитьОбъект() у непонятно чего.
   Морфиус
 
20 - 04.03.20 - 10:58
(19) НЕТ, могу фото прикрепить.
    СокрЛП(Выборка.Ссылка.УникальныйИдентификатор())   - 45a41c5f-5d28-11ea-baec-00155d2b2d03
    СокрЛП(Выборка.Ссылка): Заявка 0000036 от 03.03.2020 11:23:34
   Cyberhawk
 
21 - 04.03.20 - 11:02
Может у тебя автоматический режим в конфе?
   Cyberhawk
 
22 - 04.03.20 - 11:03
Ну или режим совместимости 8.2. Там конечно же будут либо в СУБД, либо упр. при ПолучитьОбъект в транзакции
   Морфиус
 
23 - 04.03.20 - 11:04
Вот более ранний лог.
"Ошибка: Ошибка подключения (26.11.2019 13:43:51){ОбщийМодуль.ОбменЗаявками.Модуль(2073)}: Ошибка при вызове метода контекста (ПолучитьОбъект):"  .....

Стоп. Кажется догадался, надо записать ВЕСЬ "Описание ошибки". Похоже здесь причина. Всем спасибо. Буду искать.
   Морфиус
 
24 - 04.03.20 - 11:09
Логирование шло не в ЖР, а там ограниченная длина строки. Похоже, что-то не увидел.


Список тем форума
Рекламное место пустует  Рекламное место пустует
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.