В процессе сопровождения распределенных информационных баз (РИБ) программисты часто сталкиваются с необходимостью глубокой очистки периферийного узла. Стандартные механизмы платформы накладывают ограничения на удаление данных в подчиненных базах, так как эти данные могут иметь миграцию из главного узла. В таких случаях часто применяется стратегия временного превращения периферийной базы в автономную, проведения необходимых манипуляций и последующего возврата статуса РИБ.
Однако при попытке программно восстановить связь с главным узлом часто возникает ошибка: "Объект не найден (битая ссылка)". В этой статье мы разберем, почему это происходит, как правильно манипулировать планами обмена и как восстановить работоспособность обмена без потери целостности данных.
Рассмотрим стандартную ошибку начинающего разработчика. При попытке «отвязать» базу используется метод ПланыОбмена.УстановитьГлавныйУзел(Неопределено). Перед этим ссылка на главный узел сохраняется в файл или переменную. После очистки данных разработчик пытается вернуть эту ссылку обратно.
Проблема заключается в том, что ссылка в 1С — это уникальный идентификатор (GUID). Когда вы очищаете базу или создаете ее заново из файла конфигурации (cf), таблицы планов обмена могут быть пустыми или пересозданными. Сохраненный GUID больше не указывает на реальную запись в базе данных. Система видит, что ссылка есть, но объекта с таким идентификатором в таблице плана обмена не существует. Для успешного восстановления связи нам нужно оперировать не ссылками, а Кодами узлов.
Для того чтобы корректно восстановить связь, мы должны убедиться, что в плане обмена существует элемент с кодом, в точности совпадающим с кодом главного узла в центральной базе. Проанализируем правильный подход к написанию обработки.
Шаг 1. Отключение главного узла
Прежде всего, нам нужно сделать базу независимой. Это позволит удалять любые данные, включая те, что были получены по обмену. Для этого используется метод УстановитьГлавныйУзел с параметром Неопределено.
&НаСервере
Процедура ОтключитьГлавныйУзелНаСервере()
// Проверяем, является ли база подчиненной в данный момент
Если ПланыОбмена.ГлавныйУзел() <> Неопределено Тогда
ПланыОбмена.УстановитьГлавныйУзел(Неопределено);
Сообщить("База успешно отвязана от главного узла.");
Иначе
Сообщить("База уже является автономной.");
КонецЕсли;
КонецПроцедуры
Шаг 2. Восстановление связи через поиск по коду
Теперь рассмотрим самый важный этап. При восстановлении нам нельзя полагаться на старые ссылки. Мы должны найти узел по его уникальному коду (который обычно известен заранее или может быть сохранен как текстовая строка).
&НаСервере
Процедура ВосстановитьГлавныйУзелНаСервере(КодГлавногоУзла)
// Пытаемся найти узел в плане обмена по коду
// Замените 'СинхронизацияДанныхЧерезУниверсальныйФормат' на имя вашего плана обмена
УзелСсылка = ПланыОбмена.СинхронизацияДанныхЧерезУниверсальныйФормат.НайтиПоКоду(КодГлавногоУзла);
Если УзелСсылка.Пустая() Тогда
// Если узел не найден, его необходимо создать вручную
НовыйУзел = ПланыОбмена.СинхронизацияДанныхЧерезУниверсальныйФормат.СоздатьУзел();
НовыйУзел.Код = КодГлавногоУзла;
НовыйУзел.Наименование = "Центральная база (восстановленная)";
НовыйУзел.Записать();
УзелСсылка = НовыйУзел.Ссылка;
Сообщить("Создан новый узел с кодом: " + КодГлавногоУзла);
КонецЕсли;
// Устанавливаем найденный или созданный узел в качестве главного
Попытка
ПланыОбмена.УстановитьГлавныйУзел(УзелСсылка);
Сообщить("Связь с главным узлом успешно восстановлена.");
Исключение
Сообщить("Ошибка при установке главного узла: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Проанализируем ситуацию, когда у нас нет возможности запустить обработку внутри базы (например, если конфигурация повреждена или заблокирована). Платформа 1С:Предприятие предоставляет штатный механизм для сброса признака подчиненного узла через параметры командной строки.
Для этого необходимо запустить исполняемый файл 1С с ключом /ResetMasterNode. Рассмотрим пример строки запуска для командного интерпретатора (cmd):
"C:\Program Files\1cv8\common\1cestart.exe" ENTERPRISE /F "C:\MyBase" /N "Admin" /P "Password" /ResetMasterNode
Важный момент: использование этого ключа полностью очищает информацию о главном узле. После выполнения этой команды база становится автономной, и вы сможете вносить любые изменения в структуру и данные.
При восстановлении связи в РИБ существует критический нюанс, который часто упускают: номера принятых и отправленных сообщений. Если вы создали узел заново, счетчики сообщений сбросятся в 0. При попытке загрузить первый же пакет из центральной базы вы получите ошибку о несоответствии номера сообщения.
Разберем, как программно скорректировать номера сообщений после восстановления узла:
&НаСервере
Процедура НастроитьНомераСообщений(УзелСсылка, НомерПринятого, НомерОтправленного)
УзелОбъект = УзелСсылка.ПолучитьОбъект();
УзелОбъект.НомерПринятого = НомерПринятого;
УзелОбъект.НомерОтправленного = НомерОтправленного;
УзелОбъект.Записать();
Сообщить("Счетчики сообщений обновлены.");
КонецПроцедуры
Проанализируем, какие значения сюда подставлять:
Если ваша задача — создать абсолютно чистую периферийную базу, сохранив структуру, мы рекомендуем следующий алгоритм:
ЭтотУзел. Присвойте ему код периферийной базы.ПланыОбмена.УстановитьГлавныйУзел(), как было описано выше, указав ссылку на второй элемент.Мы выяснили, что основной причиной ошибок при работе с РИБ является попытка привязки по GUID объекта, который был удален или изменен. Для стабильной работы всегда используйте поиск по коду (НайтиПоКоду) в планах обмена.
Помните:
УстановитьГлавныйУзел(Неопределено) — это единственный способ сделать базу полностью независимой внутри кода 1С.Используя приведенные примеры кода и методики, вы сможете гибко управлять периферийными базами, проводить их очистку и восстановление без риска потери связи с основной информационной системой.