При обновлении крупных распределенных информационных баз (РИБ) на базе конфигураций 1С:Управление торговлей 11, 1С:ERP Управление предприятием или 1С:Комплексная автоматизация администраторы и разработчики часто сталкиваются с неожиданными сбоями при выполнении отложенных обработчиков обновления. Особенно остро проблема проявляется после успешного обновления главного узла, последующего обновления подчиненных узлов и запуска обратного обмена данными.
В этой статье мы подробно разберем, почему возникает неприятная ошибка, связанная с получением узла плана обмена ОбновлениеИнформационнойБазы, проанализируем внутренние механизмы Библиотеки стандартных подсистем (БСП) и рассмотрим несколько надежных способов решения проблемы: от официальных патчей до ручной правки «на лету» через отладчик и написания собственного расширения конфигурации.
Для начала давайте проанализируем технологический стек и контекст проблемы. Ошибка заявляет о себе при запуске базы в режиме «Предприятие» на этапе выполнения дополнительных (отложенных) процедур обработки данных. В журнале регистрации фиксируется следующий стек вызовов:
Процедура "КоммерческиеПредложенияДокументыУТ.ОбработатьДанныеДляПереходаНаНовуюВерсию" обработки данных завершилась с ошибкой:
Невозможно получить узел плана обмена ОбновлениеИнформационнойБазы, т.к. не передан номер очереди.
{ПланОбмена.ОбновлениеИнформационнойБазы.МодульМенеджера(53)}: ВызватьИсключение НСтр("ru = 'Невозможно получить узел плана обмена ОбновлениеИнформационнойБазы, т.к. не передан номер очереди.'");
{ОбщийМодуль.ОбновлениеИнформационнойБазы.Модуль(3772)}: Возврат ПланыОбмена.ОбновлениеИнформационнойБазы.УзелПоОчереди(Очередь);
...
Давайте разберемся, почему это происходит с точки зрения архитектуры БСП. Начиная с определенных версий (ориентировочно с БСП 3.1.3), разработчики фирмы 1С начали активно внедрять параллельный режим выполнения отложенных обработчиков обновления. В новой архитектуре система автоматически определяет зависимости между обработчиками и объектами метаданных, выстраивая оптимальный граф выполнения. При этом жесткая привязка к очередям отпадает, и для новых параллельных обработчиков значение переменной Очередь по умолчанию инициализируется как 0.
Однако в модуле менеджера плана обмена ОбновлениеИнформационнойБазы осталась старая жесткая проверка, которая не была адаптирована под параллельный режим:
Если ТипЗнч(Очередь) <> Тип("Число") Или Очередь = 0 Тогда
ВызватьИсключение НСтр("ru = 'Невозможно получить узел плана обмена ОбновлениеИнформационнойБазы, т.к. не передан номер очереди.'");
КонецЕсли;
В локальной (однопользовательской) базе этот код может не вызываться напрямую, но в распределенной базе (РИБ) при обмене данными система пытается зарегистрировать изменения для синхронизации состояния обновления между узлами. При обращении к методу ВыбратьСсылкиДляОбработки передается нулевой номер очереди, что незамедлительно приводит к аварийному завершению работы отложенного обработчика.
Фирма 1С официально зарегистрировала эту ошибку под номером 00-00304292. Давайте рассмотрим, какими путями мы можем решить эту проблему в нашей рабочей базе.
Поскольку проблема носит системный характер и признана разработчиками 1С, самым правильным и безопасным решением является обновление конфигурации до релизов, в которых этот баг уже исправлен.
Официальные исправления вошли в следующие сборки конфигураций:
Если у вас включена автоматическая загрузка исправлений и база подключена к Порталу ИТС, система должна самостоятельно скачать и установить патч с кодом EF_00_00304292. Если этого не произошло, мы можем скачать данный патч вручную из раздела обновлений на сайте поддержки пользователей 1С и установить его через меню Администрирование — Обслуживание — Обновление программы — Установленные исправления (патчи).
Если вам необходимо завершить обновление прямо сейчас, базы уже заблокированы для пользователей, а времени на установку патчей или поиск новых релизов нет, мы можем прибегнуть к маленькой хитрости и изменить значение проблемной переменной непосредственно в процессе выполнения кода.
Давайте выполним следующие шаги:
ОбновлениеИнформационнойБазыСлужебный и найдем в нем следующую строку (ориентировочно строка 6417):
Параметры.Вставить("Очередь", ОбработчикОбновления.ОчередьОтложеннойОбработки);
ОбработчикОбновления.ОчередьОтложеннойОбработки с 0 на 1.После прохождения этих шагов обновление завершится успешно, и база вернется в штатный режим работы. Однако при последующих обновлениях ошибка может повториться, поэтому данный способ подходит только как временная мера.
Если ваша конфигурация находится на полной поддержке («на замке»), и вы не хотите снимать ее с поддержки ради исправления одной строки кода, наилучшим решением будет использование механизма расширений.
Давайте создадим простое расширение, которое скорректирует поведение функции определения узла по очереди. Выполним по шагам:
ОбновлениеИнформационнойБазы, нажмем по нему правой кнопкой мыши и выберем пункт Добавить в расширение.ОбновлениеИнформационнойБазы внутри нашего расширения.УзелПоОчереди(Очередь). Напишем код, который при передаче нулевой очереди будет подменять ее на корректный узел (например, узел первой очереди), избегая генерации исключения.Примерный шаблон программного кода для модуля менеджера плана обмена в расширении:
&Вместо("УзелПоОчереди")
Функция ИБ_УзелПоОчереди(Очередь)
// Если пришел нулевой номер очереди (характерно для параллельных обработчиков БСП)
Если Очередь = 0 Тогда
// Возвращаем узел для первой очереди, чтобы обойти жесткую проверку и не вызывать ошибку
Возврат ПланыОбмена.ОбновлениеИнформационнойБазы.НайтиПоКоду(1);
КонецЕсли;
// Во всех остальных стандартных случаях вызываем исходный платформенный алгоритм
Возврат ПродолжитьВызов(Очередь);
КонецФункции
После применения этого расширения все фоновые процедуры обновления распределенной информационной базы завершатся корректно без падений и блокировок интерфейса.
Существует еще один альтернативный способ, к которому иногда прибегают системные администраторы. Он заключается в том, чтобы заставить базу думать, будто она больше не является участником распределенной информационной базы. В таком режиме механизмы авторегистрации изменений для планов обмена отключаются, и отложенное обновление проходит без проверки очередей.
Давайте кратко рассмотрим этот алгоритм:
Неопределено).Важное предупреждение: данный метод требует предельной аккуратности, так как некорректная отвязка и обратная привязка узла РИБ может привести к сбросу номеров входящих и исходящих сообщений обмена, что повлечет за собой рассогласование миграции данных между базами. Мы рекомендуем использовать этот метод только в самых крайних случаях и при наличии свежих резервных копий всех узлов РИБ.
Мы надеемся, что приведенные методики помогут вам быстро справиться с ошибкой обновления планов обмена и успешно перевести ваши торговые системы на новые актуальные релизы программных продуктов 1С!