В распределенных информационных базах (РИБ) одной из частых проблем является своевременное обновление конфигурации на подчиненных узлах. Когда в главном узле вносятся изменения в метаданные (добавляются реквизиты, документы, справочники), эти изменения передаются в периферийную базу вместе с очередным пакетом обмена. После успешной загрузки сообщения обмена подчиненный узел «понимает», что его конфигурация отличается от конфигурации базы данных, и блокирует дальнейший прием-передачу данных до тех пор, пока не будет выполнено обновление в режиме конфигуратора.
Если на удаленной точке нет штатного администратора, обычные пользователи могут долго не замечать, что обмен приостановлен. В этой статье мы подробно разберем, как программно определить необходимость обновления конфигурации подчиненного узла, как настроить автоматическое оповещение пользователей и как полностью автоматизировать процесс применения изменений структуры базы данных.
Платформа «1С:Предприятие» предоставляет удобный и быстрый инструмент для проверки соответствия основной конфигурации и конфигурации базы данных. Для этого используется функция глобального контекста КонфигурацияИзменена().
Давайте разберем, как она работает. Данная функция возвращает значение Истина, если в базу данных загружены новые метаданные (например, в процессе чтения сообщения обмена РИБ), но они еще не были применены к самой структуре таблиц СУБД (то есть не выполнено обновление конфигурации базы данных по клавише F7 или через командную строку).
Проанализируем простейший пример использования этой функции при начале работы системы. Мы можем поместить проверку в модуль обычного или управляемого приложения, чтобы предупреждать пользователя при входе в программу.
Процедура ПриНачалеРаботыСистемы()
// Проверяем, отличается ли основная конфигурация от конфигурации БД
Если КонфигурацияИзменена() Тогда
ТекстСообщения = "Внимание! Из главного узла получены обновления программы.
|Необходимо запустить Конфигуратор и выполнить обновление базы данных (F7).
|До выполнения обновления обмен данными приостановлен!";
ПоказатьПредупреждение(, ТекстСообщения, 60, "Требуется обновление конфигурации");
КонецЕсли;
КонецПроцедуры
Этот простой код позволяет сразу при запуске программы информировать пользователей или ответственных сотрудников на торговой точке о том, что пора пригласить специалиста или запустить обновление самостоятельно.
Иногда изменения метаданных не затрагивают физическую структуру таблиц (например, изменился только код в общем модуле или форма документа). В этом случае возможно динамическое обновление системы. Чтобы определить, что база была обновлена динамически и пользователю достаточно просто перезапустить сеанс, мы можем использовать другую функцию платформы — КонфигурацияБазыДанныхИзмененаДинамически().
Рассмотрим, как можно совместить обе проверки для вывода максимально информативного сообщения:
Если КонфигурацияИзменена() Тогда
// Требуется монопольное обновление структуры БД
ВызватьИсключение "Требуется обновление конфигурации базы данных через Конфигуратор!";
ИначеЕсли КонфигурацияБазыДанныхИзмененаДинамически() Тогда
// Достаточно просто перезапустить программу
ПоказатьПредупреждение(, "Конфигурация обновлена динамически. Пожалуйста, перезапустите программу для применения изменений.", 30);
КонецЕсли;
Если мы не хотим беспокоить рядовых сотрудников удаленного узла всплывающими окнами, мы можем автоматизировать отправку уведомления системному администратору. Для этого настроим регламентное задание, которое будет периодически проверять состояние конфигурации и, в случае необходимости, отправлять письмо или сообщение в мессенджер.
Разберем пример серверной процедуры, которая может быть вызвана регламентным заданием:
Процедура ПроверитьНеобходимостьОбновления() Экспорт
Если КонфигурацияИзменена() Тогда
// Получаем параметры текущей информационной базы для идентификации
ИмяСервера = СтрокаСоединенияИнформационнойБазы();
ТемаПисьма = "Требуется обновление конфигурации на узле: " + Справочники.Валюты.СистемнаяВалюта().Наименование; // Или любой другой идентификатор филиала
ТелоПисьма = "На удаленном узле РИБ обнаружены непримененные изменения метаданных." + Символы.ПС +
"Строка соединения: " + ИмяСервера + Символы.ПС +
"Пожалуйста, выполните обновление конфигурации базы данных.";
// Здесь должен быть ваш код отправки почтового сообщения (например, через СистемнуюУчетнуюЗапись)
ОтправитьУведомлениеАдминистратору(ТемаПисьма, ТелоПисьма);
КонецЕсли;
КонецПроцедуры
Для того чтобы полностью исключить человеческий фактор, мы можем настроить автоматическое применение изменений. Схема выглядит следующим образом: при выполнении сеанса обмена данными система определяет, что конфигурация изменена, после чего программно инициирует закрытие текущих сеансов и запускает пакетный файл обновления.
Посмотрим на пример реализации такого механизма. Сначала напишем процедуру, которая проверяет признак изменения конфигурации сразу после завершения чтения файла обмена РИБ:
Процедура ПослеЗагрузкиДанныхВПриемеОбмена()
Если КонфигурацияИзменена() Тогда
// Записываем лог или устанавливаем признак необходимости обновления для внешнего скрипта
СоздатьФайлМаркерОбновления();
// Запускаем внешний командный файл, который выполнит обновление после закрытия 1С
ЗапуститьВнешнийСкриптОбновления();
// Завершаем работу текущего сеанса 1С
ПрекратитьРаботуСистемы(Ложь);
КонецЕсли;
КонецПроцедуры
Теперь разберем, как должен выглядеть внешний скрипт (например, update.bat), который запустит конфигуратор в пакетном режиме. Этот файл создается динамически из кода 1С или хранится на диске удаленного компьютера:
@echo off
timeout /t 10 /nobreak > nul
rem Ожидаем завершения работы всех процессов 1С:Предприятия (для файловой базы)
taskkill /f /im 1cv8.exe
taskkill /f /im 1cv8c.exe
rem Запуск конфигуратора для обновления базы данных
"C:\Program Files\1cv8\8.3.12.1790\bin\1cv8.exe" CONFIG /F"C:\1C_Bases\BranchBase" /N"Admin" /P"AdminPassword" /UpdateDBCfg
rem Запуск 1С в режиме Предприятия после успешного обновления
start "" "C:\Program Files\1cv8\8.3.12.1790\bin\1cv8c.exe" /F"C:\1C_Bases\BranchBase" /N"User" /P"UserPassword"
В параметрах запуска конфигуратора мы используем ключ /UpdateDBCfg, который и отвечает за непосредственное обновление структуры таблиц базы данных. Также можно использовать дополнительные параметры, такие как -WarningsAsErrors, чтобы процесс прерывался в случае возникновения критических предупреждений платформы.
Если вы работаете с конфигурациями, созданными на базе современных версий Библиотеки стандартных подсистем (БСП), то изобретать велосипед не потребуется. В составе БСП уже есть готовые механизмы.
Давайте проанализируем, как БСП решает эту задачу:
ОбщегоНазначения.ТребуетсяОбновлениеКонфигурацииПодчиненногоУзлаРИБ(). Она инкапсулирует в себе вызовы платформенных методов и возвращает булево значение.Если вы разрабатываете собственную конфигурацию или дорабатываете старую (например, УТ 10.3), рекомендуется перенять этот опыт БСП: при обнаружении изменения метаданных жестко блокировать возможность записи новых документов и справочников, чтобы избежать повреждения ссылочной целостности базы данных до момента реструктуризации.