Как корректно отключить регистрацию изменений объектов для плана обмена, чтобы сэкономить ресурсы системы?

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

При работе с распределенными информационными базами (РИБ) или универсальными обменами данными мы часто сталкиваемся с ситуацией, когда определенные объекты конфигурации регистрируются для передачи на узел, где они совершенно не нужны — решить эту задачу поможет обработка массовой регистрации изменений для обмена. Это приводит к раздуванию таблиц регистрации изменений (например, dbo._DocumentChngR...), увеличению времени обмена и лишней нагрузке на диск.

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

Почему возникает проблема лишней регистрации?

По умолчанию в планах обмена часто используется механизм авторегистрации. Это удобно для старта, но в промышленных масштабах может стать проблемой. Даже если данные узла нигде не используются, сам факт наличия записи в таблице регистрации потребляет ресурсы. Мы рассмотрим три основных стратегии решения этой задачи, от простых настроек до программного вмешательства.

Способ 1. Изменение состава Плана обмена (Метаданные)

Самый очевидный способ, который приходит в голову первым — открыть конфигуратор, найти нужный План обмена, перейти в его состав и снять галочку напротив ненужного справочника или документа.

Давайте проанализируем, почему этот способ, несмотря на свою простоту, может быть опасен. Этот вариант обсуждался в начале дискуссии, и справедливо было замечено, что у него есть "подводные камни".

Риски изменения состава плана обмена:

  1. Физическое удаление таблиц. Когда вы снимаете флаг включения объекта в состав плана обмена и обновляете конфигурацию базы данных, платформа 1С физически удаляет таблицу регистрации изменений для этого объекта, связанную с данным планом обмена.
  2. Влияние на другие узлы. Таблица регистрации изменений одна на весь План обмена (как объект метаданных). Если у вас есть несколько узлов (например, "Центр", "Склад", "Бухгалтерия") в рамках одного плана, и вы исключаете объект из состава, он перестанет регистрироваться для всех узлов. Если хотя бы одному узлу эти данные нужны — этот способ вам не подходит.
  3. Потеря истории. Вся накопленная, но еще не переданная информация об изменениях будет безвозвратно удалена.

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

Способ 2. Использование Правил регистрации объектов (БСП)

Если ваша конфигурация построена на базе Библиотеки Стандартных Подсистем (БСП), для изучения которой существуют удобные справочники с примерами, — а это большинство современных типовых решений (1С:ERP, 1С:УТ, 1С:Бухгалтерия) — у вас есть мощный инструмент: Правила регистрации объектов (ПРО).

Этот метод позволяет настроить логику без изменения кода конфигурации, работая в режиме "Предприятие".

Как это работает:

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

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

Способ 3. Программное отключение регистрации (Рекомендуемый)

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

Мы будем использовать подписку на событие ПередЗаписью. Для реализации этого подхода лучше всего использовать механизм Расширений конфигурации, который позволяет гибко дорабатывать систему, не снимая основную конфигурацию с поддержки — для этого подойдёт расширение для отключения регистрации объектов в EnterpriseData. Сама работа с расширениями становится проще при использовании специальных утилит, таких как обработка для группового управления расширениями или инструменты для анализа изменений и потенциальных конфликтов.

Логика работы свойства ОбменДанными

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

Давайте рассмотрим пример кода, который необходимо поместить в подписку на событие ПередЗаписью для нужных объектов.

Вариант А: Полная блокировка автозаполнения

Самый быстрый способ. Если установить свойство АвтоЗаполнение в значение Ложь, платформа даже не будет пытаться определить, нужно ли регистрировать объект согласно настройкам метаданных.


Процедура ПередЗаписьюДокумента(Источник, Отказ, РежимЗаписи, РежимПроведения)
    
    // Если это загрузка данных из другого узла, то прерываем выполнение,
    // чтобы не зациклить обмен или не сломать логику загрузки.
    Если Источник.ОбменДанными.Загрузка Тогда
        Возврат;
    КонецЕсли;

    // Полностью отключаем механику определения получателей платформой
    Источник.ОбменДанными.Получатели.АвтоЗаполнение = Ложь;
    
    // На всякий случай очищаем коллекцию, если туда что-то попало ранее
    Источник.ОбменДанными.Получатели.Очистить();

КонецПроцедуры

Вариант Б: Выборочное удаление получателя

Если вам нужно, чтобы объект уходил на узел "Бухгалтерия", но не регистрировался для узла "Мобильное приложение", код нужно немного усложнить. Мы оставляем АвтоЗаполнение = Истина (по умолчанию), но вручную удаляем конкретный узел из коллекции получателей.


Процедура ПередЗаписьюСправочника(Источник, Отказ)
    
    Если Источник.ОбменДанными.Загрузка Тогда
        Возврат;
    КонецЕсли;
    
    // Находим ссылку на узел, для которого хотим запретить регистрацию
    // В реальном коде лучше использовать кэширование или параметры сеанса, 
    // чтобы не искать узел запросом при каждой записи.
    НежелательныйУзел = ПланыОбмена.МобильноеПриложение.НайтиПоКоду("Mob01");
    
    // Удаляем конкретный узел из списка получателей
    Источник.ОбменДанными.Получатели.Удалить(НежелательныйУзел);

КонецПроцедуры

Важный нюанс: Удаление объектов

В обсуждении часто забывают, что регистрация происходит не только при записи или изменении, но и при удалении объекта. Если вы настроили логику только в событии ПередЗаписью, то при удалении элемента справочника в таблицу изменений все равно попадет запись (типа DeleteObject).

Чтобы полностью исключить узел из обмена, необходимо создать аналогичную подписку на событие ПередУдалением и прописать там ту же логику очистки получателей.


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

    // Также отключаем регистрацию факта удаления
    Источник.ОбменДанными.Получатели.АвтоЗаполнение = Ложь;
    Источник.ОбменДанными.Получатели.Очистить();

КонецПроцедуры

Чего делать не стоит: Регламентная очистка

Иногда встречается предложение (вариант 3 из обсуждения) оставить регистрацию как есть, но создать регламентное задание, которое раз в сутки будет чистить таблицы изменений запросом или методом УдалитьРегистрациюИзменений.

Давайте разберем, почему это плохая практика:

  1. Двойная работа. Система сначала тратит ресурсы на запись в таблицу изменений, а потом вы тратите ресурсы на удаление оттуда.
  2. Раздувание базы (Bloat). Постоянная вставка и удаление записей приводит к фрагментации индексов и таблиц в базе данных — оценить масштаб проблемы поможет анализ объема базы и поиск тяжелых таблиц. Таблицы _ChangeR могут оставаться большими по занимаемому месту на диске, даже если они пустые (эффект "дырок" в файле БД).
  3. Риск коллизий. Между моментом регистрации и моментом очистки может произойти сеанс обмена, и ненужные данные все-таки успеют улететь.

Итоговое резюме

Для исключения объектов из регистрации на узлах наиболее правильным подходом является комбинация методов:

  1. Если объект не нужен ни в одном узле данного плана обмена — исключите его из состава плана обмена в метаданных (с пониманием, что история обмена будет сброшена).
  2. Если нужно гибкое управление — используйте расширение конфигурации, придерживаясь принятых стандартов и методик разработки. Создайте подписки на события ПередЗаписью и ПередУдалением для нужных типов объектов. В коде подписки устанавливайте Источник.ОбменДанными.Получатели.АвтоЗаполнение = Ложь.
  3. Для конфигураций на БСП без возможности доработки кода используйте настройку "Правила регистрации объектов" в режиме Предприятия.
← На главную