При работе с распределенными информационными базами (РИБ) разработчики часто сталкиваются с ситуацией, когда стандартный механизм ПланыОбмена.ЗаписатьИзменения() перестает удовлетворять потребностям бизнеса. Это может быть связано с огромными транзакциями, блокировками таблиц или необходимостью порционной выгрузки данных через динамические запросы. Однако при переходе на ручное формирование XML-сообщений возникает критическая проблема: как передать изменения метаданных (конфигурации) в подчиненные узлы?
Стандартный метод платформы автоматически помещает бинарный образ изменений конфигурации в заголовок сообщения обмена. При ручной сборке XML-файла через ЗаписьXML доступа к этому низкоуровневому механизму формирования «блока конфигурации» у разработчика нет. В данной статье мы разберем стратегии решения этой задачи, основанные на опыте практикующих специалистов.
Разберем ситуацию: платформа 1С хранит регистрацию изменений метаданных в скрытых системных таблицах СУБД. Когда мы вызываем ЗаписатьИзменения(), система проверяет эти таблицы и, если есть зарегистрированные изменения конфигурации, упаковывает их в специальный формат внутри XML-сообщения. Если же мы используем ВыбратьИзменения() или динамические запросы к таблицам регистрации, мы получаем доступ только к данным (справочникам, документам), но не к самим объектам метаданных.
Проблема усугубляется тем, что подчиненный узел примет изменения конфигурации только в том случае, если сообщение пришло от узла, который в данной базе назначен Главным. Попытки просто «подсунуть» cf-файл или использовать сторонние механизмы часто приводят к конфликтам версий и нарушению целостности РИБ.
Это наиболее надежный и рекомендуемый способ. Суть его заключается в разделении ответственности между двумя разными планами обмена. Рассмотрим этот метод по шагам:
ПланыОбмена.ЗаписатьИзменения() по «пустому» РИБ-плану. Платформа сама увидит изменения метаданных и запишет их в заголовок маленького XML-файла, в котором не будет тяжелых данных, а значит, выгрузка пройдет мгновенно и без блокировок.Такой подход позволяет сохранить стабильность РИБ и при этом использовать гибкость собственных алгоритмов для передачи оперативной информации.
Иногда возникают ситуации, когда конфигурация в подчиненном узле настолько «отстала» или повреждена, что стандартный обмен не проходит. В этом случае мы можем временно разорвать и восстановить связь с главным узлом программно.
Проанализируем алгоритм действий в подчиненном узле:
1. Отключение связи с главным узлом: Чтобы иметь возможность загрузить конфигурацию из файла напрямую, необходимо «снять» признак подчиненности. Это делается методом:
ПланыОбмена.УстановитьГлавныйУзел(Неопределено);
2. Загрузка конфигурации: После этого можно выполнить загрузку .cf файла программно или через пакетный режим конфигуратора. При этом база воспринимается как автономная.
3. Восстановление связи: После успешного обновления метаданных необходимо вернуть базу в состав РИБ, указав ссылку на узел главного сервера:
ГлавныйУзелСсылка = ПланыОбмена.ГлавныйУзел().ПолучитьОбъект().Ссылка; // Или найти по коду
ПланыОбмена.УстановитьГлавныйУзел(ГлавныйУзелСсылка);
Важный нюанс: После такой операции в подчиненном узле часто остается регистрация изменений конфигурации «самого себя». Ее необходимо очистить, иначе при следующем обмене платформа может выдать ошибку о несовпадении версий или попытаться выгрузить изменения обратно.
Рассмотрим более радикальный, но эффективный метод для тех, кто хочет полностью автоматизировать процесс, минуя XML-сообщения. Мы можем использовать возможности запуска конфигуратора из кода 1С.
Алгоритм на стороне Главного узла:
/DumpCfg.Алгоритм на стороне подчиненного узла:
ЗапуститьСистему.Пример командной строки для обновления конфигурации базы данных:
"C:\Program Files\1cv8\common\1cestart.exe" DESIGNER /F "ПутьКБазе" /N "Логин" /P "Пароль" /UpdateCfg "ПутьКФайлу.cf" /UpdateDBCfg
После такого обновления необходимо использовать метод ПланыОбмена.УстановитьГлавныйУзел(), чтобы подтвердить системе, что конфигурация теперь соответствует главному узлу.
Выясним причину, почему нельзя совмещать загрузку данных и конфигурации в одном сложном алгоритме. В платформе 1С существует жесткое ограничение: если метод ПрочитатьИзменения() встречает в сообщении изменения метаданных, он загружает их в область временного хранения («принятые изменения») и блокирует дальнейшее выполнение кода в текущем сеансе до тех пор, пока конфигурация базы данных не будет обновлена.
Поэтому, если вы реализуете свой обмен, следуйте правилу: сначала обновляем конфигурацию отдельным сообщением, затем передаем данные.
Подведем итог: для реализации выгрузки изменений конфигурации при кастомном обмене данными лучше всего использовать комбинированный подход. Используйте стандартный «пустой» РИБ-план обмена для транспорта метаданных и свои механизмы (динамические запросы, порционную выгрузку) для обмена оперативной информацией через планы обмена без признака РИБ. Это обеспечит максимальную производительность и сохранит целостность вашей распределенной системы.