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