Как предотвратить обратную выгрузку данных в узел-источник при обмене (эффект эха)

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

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

Метод 1. Использование механизма «ДополнительныеСвойства» и программная очистка регистрации

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

Разберем по шагам реализацию этого метода:

  1. Передача контекста узла-отправителя. В обработчике загрузки данных (например, в правилах обмена или модуле загрузки) нам необходимо поместить ссылку на узел-отправитель в коллекцию ДополнительныеСвойства загружаемого объекта.
  2. Обработка в модуле объекта. В процедуре ПриЗаписи или ПередЗаписью мы проверяем наличие этого свойства.
  3. Удаление регистрации. Если свойство найдено, мы используем метод ПланыОбмена.УдалитьРегистрациюИзменений().

Посмотрим на пример кода, который можно разместить в модуле объекта (например, справочника СерииНоменклатуры или документа):


Процедура ПриЗаписи(Отказ)
    Если ОбменДанными.Загрузка Тогда
        Возврат;
    КонецЕсли;

    // Проверяем, есть ли информация об узле-источнике
    Если ДополнительныеСвойства.Свойство("УзелИсточник") Тогда
        УзелДляИсключения = ДополнительныеСвойства.УзелИсточник;
        
        // Отменяем регистрацию только для того узла, который прислал данные
        ПланыОбмена.УдалитьРегистрациюИзменений(УзелДляИсключения, Ссылка);
    КонецЕсли;
КонецПроцедуры

Этот способ хорош тем, что объект всё равно будет зарегистрирован для всех остальных фронт-офисов, обеспечивая актуальность данных во всей сети, но не создаст «эхо» для отправителя.

Метод 2. Использование штатных возможностей БСП

Если ваша конфигурация разработана на базе Библиотеки стандартных подсистем (БСП), то задача упрощается. В БСП механизм предотвращения зацикливания уже частично реализован. Рассмотрим, как он работает.

При использовании типовых универсальных обменов БСП, в ДополнительныеСвойства объекта при загрузке автоматически записывается структура ДляОбменаДанными, содержащая поле Отправитель. В системе существуют типовые подписки на события, например, ПриЗаписиОбъектаДляОбменаДанными. Эти подписки анализируют наличие отправителя и блокируют регистрацию изменений для него.

Для реализации этого подхода убедитесь, что:

Метод 3. Настройка правил регистрации данных (ПРД)

Выясним, как можно решить проблему на уровне «Конвертации данных». Если вы используете внешние файлы правил регистрации (XML), вы можете прописать логику фильтрации прямо в них. Это позволяет не менять код самих объектов в конфигурации.

В ПРД для конкретного объекта в обработчике «Перед обработкой» или «При регистрации» (в зависимости от версии КД) можно использовать следующий алгоритм:


// Пример логики в правилах регистрации
Если Объект.УзелПервичногоВвода = УзелОбмена Тогда
    Отказ = Истина;
КонецЕсли;

Важный нюанс: Для этого метода в самом объекте (например, в серии) должен быть реквизит, хранящий ссылку на узел, в котором этот объект был создан изначально. Это надежный способ, который часто применяется в распределенных базах данных (РИБ).

Метод 4. Метод «Сверки версий» через хеширование

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

Алгоритм действий следующий:

  1. При выгрузке данных в узел рассчитывается MD5-хеш (или любой другой быстрый хеш) значимых полей объекта.
  2. Этот хеш сохраняется в специальном регистре сведений на стороне центральной базы в разрезе «Объект — Узел».
  3. В следующий раз в обработчике ПередВыгрузкой мы снова считаем текущий хеш объекта.
  4. Если текущий хеш совпадает с тем, что хранится в регистре для данного узла, мы устанавливаем Отказ = Истина.

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

Метод 5. Глобальный перехват в Плане Обмена

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

Рассмотрим пример логики: если мы можем определить автора изменений по префиксу документа или по специальному реквизиту «Подразделение», мы можем программно запретить регистрацию.


// В модуле плана обмена
Процедура ПриРегистрацииИзменений(Данные, Узлы)
    // Логика анализа данных и выборочного удаления узлов из массива "Узлы"
    // Если данные созданы во фронте №1, удаляем этот узел из коллекции получателей
КонецПроцедуры

Резюме

Выбор конкретного метода зависит от архитектуры вашего решения. Если используется БСП, наиболее правильным будет следование её стандартам через ДополнительныеСвойства. Если же обмен самописный и на «тупых» фронтах, лучше всего подойдет Метод 1 (удаление регистрации при записи) или Метод 3 (использование ПРД), если вы не хотите вносить изменения в структуру метаданных. Помните, что экономия трафика не только ускоряет обмен, но и снижает вероятность возникновения конфликтов блокировок в высоконагруженных системах.

← На главную