|
|
|
Исключение при выполнении ДокументСсылка.ПолучитьОбъект(). Фоновые задания. | ☑ | ||
|---|---|---|---|---|
|
0
Морфиус
03.03.20
✎
16:42
|
Есть такой код, выполняемый в конкуренции фоновых заданий на сервере (8.3.15 в разных релизах) - одна функция, вызываемая из разных фоновых заданий.
Запрос = Новый Запрос("ВЫБРАТЬ ПЕРВЫЕ 1 | Заявка.Ссылка |ИЗ | Документ.Заявка КАК Заявка |ГДЕ | Заявка.ПользовательСайта = &ПользовательСайта | И НЕ Заявка.ПометкаУдаления "); Запрос.УстановитьПараметр("ПользовательСайта",ПользовательЗаявки.Ссылка); Выборка = Запрос.Выполнить().Выбрать(); Если Выборка.Следующий() Тогда Попытка Док = Выборка.Ссылка.ПолучитьОбъект(); Исключение ЗаписьЖурналаРегистрации(" Не удалось ПолучитьОбъект() Док.Заявка",УровеньЖурналаРегистрации.Ошибка,,, "Дамп | Заявка УИД : " + СокрЛП(Выборка.Ссылка.УникальныйИдентификатор()) +" | Заявка : " + СокрЛП(Выборка.Ссылка) +" | Размер выборки : " + Выборка.Количество() + " | Блокирован ? : нельзя проверить, так как не создан документ."); КонецПопытки; // Далее по причине конкуренции, ставим блокировку на объект. БлокировкаДанных = Новый БлокировкаДанных; ЭлементБлокировки = БлокировкаДанных.Добавить("Документ.Заявка"); ЭлементБлокировки.УстановитьЗначение("Ссылка", Док.Ссылка); ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный; БлокировкаДанных.Заблокировать(); Возврат Док; КонецЕсли; Проблема: Иногда, примерно раз в две недели, ДокументСсылка.ПолучитьОбъект() сваливается в исключение. Текст Ошибки: ОбщийМодуль.ОбменЗаявками.Модуль(2073): Ошибка при вызове метода контекста (ПолучитьОбъект) Согласно 1С документации: ДокументСсылка.ПолучитьОбъект() не генерирует исключение. Удалось выяснить что ссылка живая СокрЛП(Выборка.Ссылка.УникальныйИдентификатор()) - 45a41c5f-5d28-11ea-baec-00155d2b2d03 Представление документа также считалось из БД СокрЛП(Выборка.Ссылка): Заявка 0000036 от 03.03.2020 11:23:34 Дата создания документа на 30 минут раньше времени исключения, т.е. документ присутствует в БД. Как обойти ошибку? Ставить таймаут на несколько секунд и повторять снова? Какие идеи? |
|||
|
1
vicof
03.03.20
✎
16:45
|
А зачем получать объект в этой процедуре?
|
|||
|
2
ДенисЧ
03.03.20
✎
16:45
|
Нужно смотреть в модуль объекта
|
|||
|
3
fisher
03.03.20
✎
16:49
|
Добавь в запись ЖР исходное ОписаниеОшибки() и не морочь голову. С большой вероятностью при следующем падении ты уже будешь знать ошибку.
|
|||
|
4
fisher
03.03.20
✎
16:56
|
Варианты навскидку:
- ошибка в секции инициализации модуля объекта - падение по таймауту, если данные объекта заблокированы в СУБД (исключительные блокировки СУБД). Но в версионнике такого по идее в режиме управляемых блокировок быть не должно. |
|||
|
5
Морфиус
03.03.20
✎
16:57
|
ОписаниеОшибки() было в предыдущей версии и оно на экране: Ошибка при вызове метода контекста (ПолучитьОбъект)
В модуле объекта кроме ОбработкаПроведения() нет функций/процедур обработки событий объекта, или переменных. Для этого документа нет ПодписокНаСобытия. Кроме того, В ОписаниеОшибки стек глубже не раскручивается, Только "Ошибка при вызове метода контекста (ПолучитьОбъект)". |
|||
|
6
fisher
03.03.20
✎
16:58
|
(5) Какая СУБД? Какой режим блокировок в конфигурации?
|
|||
|
7
Морфиус
03.03.20
✎
17:00
|
Режим управления блокировкой данных: Управляемый. Режим совместимости: 8.3.8 (Старенькая конфигурация)
|
|||
|
8
fisher
03.03.20
✎
17:02
|
СУБД какая? Важно понять, в каком она у тебя работает режиме. Версионника или блокировочника. Т.е. если mssql - используется ли режим снэпшотов.
|
|||
|
9
Морфиус
03.03.20
✎
17:02
|
СУБД - Скорее всего MS - Mycrosoft SQL Server (это у клиента). На Linux Postgress ошибки не наблюдал, но статистики мало.
|
|||
|
10
Сияющий в темноте
03.03.20
✎
17:02
|
кстати,если в модуле документа кинуть исключение,то оно прилетит в код получения обьекта по ссылке,что достаточно логично.
так что сама процедура исключений не генерит,но этого нельзя сказать про код модуля. |
|||
|
11
fisher
03.03.20
✎
17:10
|
(9) Если старый mssql который работает в режиме блокировочника с 1С, то гипотетически могу предположить попадание ПолучитьОбъект() как раз на блокировку при попытке изменения данных документа в конкурирующем процессе. А почему, кстати, ты сначала объект получаешь а потом блокировку накладываешь? Почему не наоборот?
|
|||
|
12
Морфиус
03.03.20
✎
17:13
|
>> Важно понять, в каком она у тебя работает режиме. Версионника или блокировочника. Т.е. если mssql - используется ли режим снэпшотов.
Понятно что проблемы с СУБД. Только это из плоскости, что нельзя изменить. Программа разрабатывается и тестируется на разных платформах. 1С-ка НЕ должна исключение выбрасывать. И еще раз - Представление из БД считалось, А блокировка объекта проверяется после создания объекта. >> так что сама процедура исключений не генерит,но этого нельзя сказать про код модуля Не совсем понял. Я конечно попробую версию модуля документа.... Но там ничего нет. Может откомпилировать не может, какие-то функции в фоновом под запретом? Но это мысли себе на заметку. >> А почему, кстати, ты сначала объект получаешь а потом блокировку накладываешь? Что бы исключить блокировку себя с собой "для чистоты эксперимента" |
|||
|
13
Морфиус
03.03.20
✎
17:24
|
Конкуренция может быть любая. Если объект заблокирован - это нормально, даже на производительность не влияет. Должен быть инструмент разрешения блокировки. Я попробую снять поставить таймаут, и посмотреть, будет ли создаваться объект. Идею с ошибкой в модуле документа считаю маловероятной - две недели между исключениями интенсивной нагрузки все работает ...
|
|||
|
14
fisher
03.03.20
✎
17:38
|
Я не исключаю, что "сваливаться" получение объекта может как раз по причине попадания на исключительную управляемую блокировку. Но не уверен. В принципе, это легко можно проверить.
Если тебе нужен механизм очереди обработки документов конкурирующими процессами, то как вариант вместо управляемой блокировки можно использовать объектную блокировку (метод Заблокировать()) не боясь, что будет конфликт с другими видами блокировок. |
|||
|
15
pechkin
03.03.20
✎
17:51
|
нужно сначала делать блокировку (в транзакции), а потом получать и изменять.
иначе помимо невозможности получить можно словить: объект был изменен |
|||
|
16
pechkin
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 |
|||
|
21
Cyberhawk
04.03.20
✎
11:02
|
Может у тебя автоматический режим в конфе?
|
|||
|
22
Cyberhawk
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
|
Логирование шло не в ЖР, а там ограниченная длина строки. Похоже, что-то не увидел.
|
| Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |