При обновлении крупных или доработанных конфигураций 1С на базе Библиотеки стандартных подсистем (БСП) разработчики часто сталкиваются с ситуацией, когда часть процедур обновления не запускается автоматически. Особенно остро эта проблема встает при наличии в базе сторонних или кастомизированных модулей (например, решений от компании «БИТ»).
В этой статье мы подробно разберем, как устроен механизм отложенного обновления БСП, как запустить обработчики принудительно через интерфейс, программный код или параметры запуска, а также выясним, как правильно организовывать обработку больших массивов данных порциями.
Прежде чем переходить к написанию кода или использованию внешних утилит, попробуем задействовать штатные интерактивные возможности БСП. Если обработчики обновления зарегистрированы в системе корректно, но просто ожидают своей очереди, мы можем запустить их вручную.
Выполним следующие шаги:
Если этот вариант не приносит результата (например, когда выполнение обработчиков было аварийно прервано или заблокировано из-за ошибок в коде (поможет инструмент отладки кода в режиме Предприятие)), нам поможет специализированная форма мониторинга обновлений:
Этот интерфейс позволяет точечно отслеживать состояние каждого обработчика, видеть детальные логи ошибок и форсировать выполнение зависших задач — поможет мониторинг фоновых заданий и ошибок.
Бывают ситуации, когда нам требуется выполнить обновление в монопольном режиме, гарантируя, что ни один пользователь не зайдет в систему, либо когда мы пишем собственную сервисную внешнюю обработку. Писать «велосипеды» с ручным поиском процедур обновления не нужно — в БСП для этого предусмотрен готовый программный интерфейс.
Для принудительного последовательного выполнения всех отложенных процедур обновления в текущем сеансе (в один поток, без привлечения фоновых заданий) используем следующий вызов:
ОбновлениеИнформационнойБазыСлужебный.ВыполнитьОтложенноеОбновлениеСейчас();
Эта процедура самостоятельно управляет ходом выполнения, считывает настройки БСП, поочередно запускает зарегистрированные обработчики обновлений и корректно фиксирует результаты их выполнения в системных регистрах. Она идеально подходит для сценария, когда базу нужно обновить гарантированно и до конца за один сеанс.
Если мы автоматизируем процесс обновления баз на сервере с помощью скриптов (батников или bash-скриптов), нам будет полезно использовать параметры запуска платформы «1С:Предприятие 8». Мы можем передать специальный ключ запуска в параметре /C.
Рассмотрим основные параметры:
/C ВыполнитьОтложенноеОбновлениеСейчас — принудительно запускает сеанс 1С в режиме выполнения всех отложенных обработчиков обновления. База выполнит все процедуры в один поток и завершит работу. Это исключает необходимость заходить в интерфейс и нажимать кнопки вручную./C ЗапуститьОбновлениеИнформационнойБазы — форсирует запуск процедур обновления и обработку вспомогательных данных. Это особенно полезно, если версия конфигурации формально не изменилась, но нам нужно заново инициализировать механизмы обновления или выполнить «звездочные» (универсальные) обработчики./C ОтключитьЛогикуНачалаРаботыСистемы — отключает выполнение стартовых проверок, обработчиков первого запуска и предупреждений. Позволяет администратору беспрепятственно войти в аварийную базу для исправления ошибок обновления.В процессе обновления баз часто требуется обработать миллионы существующих документов. Если попытаться прочитать и перезаписать их все в рамках одной транзакции, система неизбежно столкнется с нехваткой оперативной памяти, а СУБД наложит избыточные блокировки на таблицы.
Именно поэтому стандарт БСП предписывает выполнять обработку порциями (обычно по 1000 элементов). Рассмотрим пример функции, выбирающей документы ПриходныйКассовыйОрдер, в которых еще не заполнена табличная часть распределения платежа:
Процедура ПриходныйКассовыйОрдерСформироватьРаспределениеПлатежа(Параметры) Экспорт
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1000
| Реквизиты.Ссылка КАК Ссылка,
| Реквизиты.Дата КАК Дата
|ИЗ
| Документ.ПриходныйКассовыйОрдер КАК Реквизиты
| ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
| РаспределениеБюджета.Ссылка КАК Ссылка
| ИЗ
| Документ.ПриходныйКассовыйОрдер.бит_РаспределениеБюджета КАК РаспределениеБюджета
|
| СГРУППИРОВАТЬ ПО
| РаспределениеБюджета.Ссылка) КАК РаспределениеБюджета
| ПО Реквизиты.Ссылка = РаспределениеБюджета.Ссылка
|ГДЕ
| РаспределениеБюджета.Ссылка ЕСТЬ NULL
|
|УПОРЯДОЧИТЬ ПО
| Дата УБЫВ,
| Ссылка УБЫВ";
РезультатЗапроса = Запрос.Выполнить();
Если РезультатЗапроса.Пустой() Тогда
Параметры.ОбработкаЗавершена = Истина;
Возврат;
КонецЕсли;
Параметры.ОбработкаЗавершена = Ложь;
// Здесь должна следовать логика обработки выборки документов...
КонецПроцедуры
Обратите внимание на конструкцию ВЫБРАТЬ ПЕРВЫЕ 1000. Эта процедура вызывается системой БСП многократно в цикле до тех пор, пока параметр Параметры.ОбработкаЗавершена не примет значение Истина.
Если же мы пишем внешнюю обработку и хотим выполнить этот процесс самостоятельно в один проход, мы должны организовать бесконечный цикл с транзакциями. Разберем правильный шаблон реализации такого алгоритма:
ПараметрыОбработки = Новый Структура("ОбработкаЗавершена", Ложь);
Пока Истина Цикл
НачатьТранзакцию();
Попытка
// Вызываем процедуру обработки очередной порции из 1000 элементов
ПриходныйКассовыйОрдерСформироватьРаспределениеПлатежа(ПараметрыОбработки);
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ЗаписьЖурналаРегистрации("ОбновлениеДанных", УровеньЖурналаРегистрации.Ошибка,,, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
ВызватьИсключение "Ошибка при обработке порции данных! Процесс остановлен.";
КонецПопытки;
// Если обработчик сообщил, что данных больше нет - выходим из цикла
Если ПараметрыОбработки.ОбработкаЗавершена Тогда
Прервать;
КонецЕсли;
КонецЦикла;
Данный подход гарантирует стабильность работы системы: в случае падения одной из порций мы не потеряем результаты обработки предыдущих успешно зафиксированных пакетов данных.
Если в вашей базе установлена доработка стороннего вендора (например, модули БИТ) и ее обработчики упорно отказываются запускаться стандартными средствами, выясним причину этой проблемы — в этом поможет архитектурный анализ конфигурации и расширений. Как правило, причин две:
Процедура ПриДобавленииОбработчиковОбновления(Обработчики) Экспорт
// Здесь должна быть регистрация обработчика с указанием имени процедуры,
// версии конфигурации и признака отложенного выполнения.
КонецПроцедуры
ВерсииПодсистем. Если версия вашей подсистемы в базе данных уже равна или выше, чем версия, для которой написан конкретный обработчик обновления, система посчитает его уже выполненным и проигнорирует. Чтобы запустить его повторно, администраторы принудительно понижают номер версии соответствующей подсистемы в регистре ВерсииПодсистем перед запуском процесса обновления.Применяя предложенные методики, мы сможем эффективно управлять ходом отложенного обновления информационной базы, избегая рутинной работы и гарантируя сохранность и согласованность данных в СУБД.