При настройке синхронизации данных между информационными базами «1С:Предприятие» разработчики часто сталкиваются со следующей проблемой: после успешной выгрузки данных из базы-источника регистрация изменений для объектов не очищается. В результате при каждом следующем сеансе обмена система повторно выгружает все ранее переданные объекты. Это приводит к колоссальному росту объема файлов обмена, увеличению нагрузки на каналы связи и замедлению работы обеих систем.
В этой статье мы подробно разберем, почему возникает эта проблема, как устроен механизм гарантированной доставки сообщений на уровне платформы 1С и какими способами можно правильно очистить регистрацию изменений.
Для того чтобы понять суть проблемы, проанализируем внутреннее устройство планов обмена. Платформа «1С:Предприятие 8» использует транзакционный механизм гарантированной доставки сообщений. Он базируется на строгом учете номеров сообщений и работает по следующему алгоритму:
Справочник.Номенклатура.Изменения). В этой таблице фиксируются ссылки на измененные элементы, узел-получатель и служебное поле НомерСообщения, которое изначально имеет значение NULL.ВыбратьИзменения() платформа выбирает все записи с пустым номером сообщения и присваивает им номер текущего исходящего пакета (например, 15). Теперь эти объекты заблокированы под номером сообщения 15.ПланыОбмена.УдалитьРегистрациюИзменений(УзелПриемник, 15), который очищает записи регистрации с номерами сообщений, меньшими или равными 15.Таким образом, если обмен настроен строго в одну сторону («выгрузили файл и забыли»), база-источник никогда не получит подтверждения от приемника. Поле НомерСообщения останется заполненным, и при следующей выгрузке платформа снова включит эти объекты в пакет обмена.
Самый простой и надежный способ решить проблему штатными средствами — настроить двусторонний обмен данными, даже если бизнес-логика требует передачи данных только в одну сторону.
Рассмотрим, как это работает на практике. При обмене через Библиотеку Стандартных Подсистем (БСП) в базе-приемнике настраивается ответная отправка данных. Обратный файл обмена будет практически пустым — он не содержит бизнес-данных (документов или справочников), а несет в себе лишь технический заголовок с номером принятого сообщения. При получении этого файла база-источник автоматически снимет объекты с регистрации.
Для реализации этого сценария выполним следующие шаги:
Выясним, что делать, если организовать обратную связь технически невозможно (например, база-приемник находится в закрытом контуре без обратного доступа). В этом случае нам придется очищать регистрацию изменений принудительно программным путем сразу после завершения выгрузки.
Важное предупреждение о безопасности данных (Race Condition):
Ни в коем случае нельзя использовать «слепую» очистку всей регистрации по узлу без указания номера сообщения. Разберем опасную ситуацию на примере:
Представим, что выгрузка тяжелого справочника длится 5 минут. На 1-й минуте выгрузился «Контрагент А». На 3-й минуте пользователь в базе-источнике изменил номер телефона этого контрагента. В таблице регистрации для него мгновенно появилась новая запись с НомерСообщения = NULL. Если на 5-й минуте после окончания выгрузки мы жестко очистим всю регистрацию по узлу, то сотрем и это новое изменение. Телефон контрагента в базе-приемнике никогда не обновится.
Чтобы избежать потери данных, мы должны удалять регистрацию строго по номеру сообщения, которое было отправлено. Посмотрим на правильный пример кода:
// Получаем узел обмена с базой-приемником
УзелОбмена = ПланыОбмена.СинхронизацияДанных.НайтиПоКоду("ПРИЕМНИК");
// Перед очисткой необходимо убедиться, что транзакция выгрузки завершена успешно
Если ОбменУспешноЗавершен Тогда
// Удаляем регистрацию только для тех объектов, которые ушли в конкретном сообщении
ПланыОбмена.УдалитьРегистрациюИзменений(УзелОбмена, НомерОтправленногоСообщения);
КонецЕсли;
Метод ПланыОбмена.УдалитьРегистрациюИзменений(), вызванный с указанием номера сообщения, удалит только те записи, которые реально попали в выгруженный файл. Все изменения, произошедшие в процессе выгрузки, останутся зарегистрированными и будут переданы в следующий раз. Если же требуется выборочно снять документы с регистрации вручную, можно применить обработку для отмены регистрации документов за период в плане обмена.
Проанализируем частые ошибки, которые совершают программисты при попытке решить проблему программно:
ПланыОбмена.ИмяПланаОбмена.ЭтотУзел(). Это грубая ошибка. Очищать регистрацию нужно для узла-получателя (базы-приемника), а не для узла самой текущей базы.Применяя правильные подходы к квитированию сообщений — будь то настройка двусторонней синхронизации БСП или аккуратное программное удаление регистрации по номеру сообщения — мы гарантируем стабильную, быструю и корректную работу механизмов интеграции в системах 1С. Для контроля состояния обменов и своевременного выявления сбоев подойдёт решение для мониторинга синхронизаций данных между базами 1С.