В практике сопровождения распределенных систем на базе 1С (не использующих РИБ) часто возникает ситуация, когда центральная база (ЦБ) уже обновлена и содержит новые реквизиты или объекты, а периферийные узлы (например, магазины или филиалы) обновляются с задержкой. В этом случае стандартный механизм регистрации изменений может привести к потере данных: если ЦБ отправит новый реквизит в старую базу, узел его проигнорирует, а регистрация в ЦБ будет очищена по подтверждению приема сообщения. Когда же узел наконец обновится, данные за прошедший период не придут автоматически, так как они уже считаются «переданными».
Рассмотрим несколько эффективных стратегий решения этой задачи, которые позволят «замораживать» или накапливать изменения до момента готовности узла-приемника.
Проанализируем подход, при котором мы создаем второй («теневой») план обмена или добавляем в существующий план специальный служебный узел. Суть метода заключается в параллельной регистрации одних и тех же данных. Процесс выглядит следующим образом:
НакоплениеИзмененийДляОбновления.Когда нам сообщают, что конкретный магазин обновил конфигурацию, мы запускаем обработку переноса регистрации:
// Примерный алгоритм переноса регистрации
Процедура ПеренестиРегистрациюНаРабочийУзел(ТеневойУзел, РабочийУзел)
Выборка = ПланыОбмена.ВыбратьИзменения(ТеневойУзел, 1);
Пока Выборка.Следующий() Цикл
ОбъектМетаданных = Выборка.Получить().Метаданные();
ПланыОбмена.ЗарегистрироватьИзменения(РабочийУзел, Выборка.Получить());
КонецЦикла;
// После переноса очищаем теневой узел
ПланыОбмена.УдалитьРегистрациюИзменений(ТеневойУзел);
КонецПроцедуры
Выясним преимущества: этот метод позволяет гарантированно сохранить список всех измененных объектов за любой период времени без вмешательства в структуру существующих файлов обмена.
Если конфигурации построены на базе «Библиотеки стандартных подсистем» (БСП), мы можем автоматизировать процесс, используя информацию о версии метаданных приемника. Рассмотрим, как это реализовать:
В БСП при каждом обмене передается номер версии конфигурации. Мы можем сохранять этот номер в регистре сведений ПараметрыОбменаДанными в центральной базе. При выгрузке данных в правилах конвертации (или в программном коде выгрузки) добавим условие:
// В обработчике "Перед выгрузкой" или аналогичном
ВерсияПриемника = ПолучитьВерсиюУзла(УзелОбмена);
Если ВерсияПриемника < "2.0.1.5" Тогда
// Если версия старая, можно пропустить выгрузку конкретного реквизита
// или пометить объект для повторной регистрации позже
Отказ = Истина;
КонецЕсли;
Разберем, что произойдет: данные не будут выгружены (и регистрация не сбросится) до тех пор, пока узел не пришлет подтверждение, что его версия стала актуальной. Однако здесь есть тонкость — если мы откажемся от выгрузки всего объекта, узел не получит и старые, важные для него данные. Поэтому лучше использовать «мягкую схему», описанную ниже.
Проанализируем ситуацию, когда добавление нового жесткого реквизита заменяется использованием механизма ДополнительныеРеквизитыИСведения. Это наиболее гибкий путь для систем с высокой частотой обновлений.
Поскольку дополнительные реквизиты хранятся в табличной части или в отдельном регистре сведений, их состав не жестко зашит в структуру объекта. При обмене:
Этот метод исключает необходимость повторной регистрации и «хранения» изменений в ЦБ.
Если мы хотим автоматизировать «хаос» из сотен магазинов, нам потребуется служебный регистр в ЦБ, например, ОчередьПеререгистрацииОбъектов. Разберем шаги внедрения:
1. При добавлении нового метаданного (реквизита) в ЦБ, мы создаем запись в этом регистре: «Объект: Справочник.Номенклатура, НоваяВерсия: 1.5, Статус: Ожидает обновления».
2. В модуле обмена при получении сообщения от узла анализируем версию его конфигурации. Как только версия становится >= 1.5, система инициирует принудительную регистрацию всех объектов данного типа для этого узла:
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ Ссылка ИЗ Справочник.Номенклатура";
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
ПланыОбмена.ЗарегистрироватьИзменения(ТекущийУзел, Выборка.Ссылка);
КонецЦикла;
Важно помнить, что полная перерегистрация может создать огромный файл обмена, поэтому рекомендуется фильтровать объекты (например, регистрировать только те, которые изменялись за последний месяц).
Рассмотрим еще один технический прием: передачу новых данных через существующие «текстовые» поля. Если в объекте есть неиспользуемое поле Комментарий или служебное поле ТехническиеДанные, мы можем упаковывать новые реквизиты в формат JSON и передавать их строкой.
Для старых узлов это будет выглядеть как обычный текст, который они сохранят в БД. Обновленные узлы в процедуре ПриЗагрузке будут парсить эту строку и распределять данные по новым реквизитам. Это позволяет избежать конфликтов на уровне XSD-схем и гарантирует доставку данных «вслепую» до момента обновления логики приемника.
Выясним, какой метод лучше подходит под ваши задачи:
Посмотрим на ситуацию с точки зрения надежности: автоматизация через версию конфигурации является наиболее профессиональным подходом, так как она исключает «человеческий фактор» и необходимость общения в чатах или через почтовых голубей. Система сама поймет, когда узел готов принять новые данные, и отправит их повторно.