Ситуация, когда код во внешней обработке выдает актуальные остатки, а то же самое регламентное задание (РЗ) выгружает «зависшие» старые данные, — одна из самых коварных в практике разработчика 1С. На первый взгляд кажется, что платформа магическим образом кэширует результат запроса, но на самом деле причины кроются в механизмах работы серверного кластера, особенностях сеансов фоновых заданий и управлении кэшем метаданных. Разберем по шагам, почему это происходит и как победить эту проблему.
Первое, что мы должны осознать: фоновое задание (ФЗ) всегда выполняется на сервере под системной учетной записью (обычно usr1cv8), в то время как внешняя обработка часто запускается в контексте клиента. Разберем основные причины расхождения данных:
ТекущаяДата(), она берет время сервера. Если сервер 1С и сервер СУБД находятся в разных часовых поясах или время на сервере 1С сбито, запрос на остатки получит неверный параметр.rphost после каждого задания. Сеансы могут использоваться повторно. Если в общем модуле используются переменные модуля (объявленные вне процедур), они могут сохранять свои значения между запусками заданий.Прежде чем чистить кэш, нам нужно убедиться, что в запрос попадают именно те параметры, которые мы ожидаем. Поскольку отладка фонового задания не всегда удобна, воспользуемся Журналом Регистрации или механизмом сообщений пользователю. Проанализируем пример кода для отладки параметров:
Процедура ВыгрузитьОстаткиНаСервере() Экспорт
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ ... ГДЕ Период = &Период";
// Используем ТекущаяДатаСеанса() вместо ТекущаяДата()
ПараметрДата = ТекущаяДатаСеанса();
Запрос.УстановитьПараметр("Период", ПараметрДата);
// Записываем параметры в Журнал Регистрации для контроля
ЗаписьЖурналаРегистрации("ОтладкаРЗ", УровеньЖурналаРегистрации.Информация, , ,
"Задание запущено. Параметр Дата: " + ПараметрДата);
// Вывод сообщений, которые можно прочитать через консоль заданий
ОбщегоНазначенияКлиентСервер.СообщитьПользователю("Текущий период запроса: " + ПараметрДата);
Результат = Запрос.Выполнить();
// ... дальнейшая логика
КонецПроцедуры
Важный момент: всегда используйте ТекущаяДатаСеанса(). Это гарантирует, что время будет соответствовать часовому поясу, установленному для информационной базы, а не случайным настройкам операционной системы на сервере.
Как показывает практика, часто помогает перевод задания в статус предопределенного. Разберем, в чем здесь логика. Когда мы создаем задание программно или через консоль, оно сохраняется в таблице регистрации заданий СУБД. При изменениях в коде или метаданных связь может «подглючивать».
Сделаем задание предопределенным в конфигураторе:
Предопределенное в значение Истина.Использование также включена.Перезагрузка сервера — это радикальный, но эффективный метод. Она принудительно очищает оперативную память рабочих процессов rphost и сбрасывает кэш конфигурации, который находится в папке sncfg внутри каталога srvinfo.
Выясним причину, по которой удаление и повторное создание задания помогает лишь на время. В некоторых версиях платформы или при использовании устаревших внешних обработок «Консоль заданий», данные о задании в памяти сервера могут не обновляться. Проанализируем правильный алгоритм обновления:
mmc-снапшот).Иногда проблема кроется глубже — на уровне СУБД. Если регламентное задание формирует абсолютно идентичный текст запроса каждый раз, SQL Server может использовать закешированный план выполнения. В редких случаях (особенно при интенсивном использовании временных таблиц) это приводит к чтению устаревших данных из буферов.
Чтобы исключить этот фактор, можно попробовать добавить в текст запроса «шум» — комментарий, который меняется при каждом запуске (например, текущее время запуска):
ТекстЗапроса = "ВЫБРАТЬ ... // " + Строка(Новый УникальныйИдентификатор());
Запрос.Текст = ТекстЗапроса;
Это заставит СУБД каждый раз пересобирать план выполнения запроса, исключая влияние старого кэша планов.
Подведем итог. Если ваше регламентное задание ведет себя неадекватно и выдает старые данные, выполните следующие действия:
ТекущаяДата() на ТекущаяДатаСеанса().sncfg) и перезапустите службу 1С.Соблюдение этих правил позволит вам избежать «мистических» ошибок и обеспечит стабильную выгрузку актуальных данных в автоматическом режиме.