Часто разработчики сталкиваются с ситуацией: процедура, запущенная из внешней обработки, отрабатывает без ошибок, но при переносе того же кода в регламентное задание возникают ошибки и транзакции принудительно отменяются. Давайте разберем, почему так происходит и как эффективно диагностировать причину.
Первое, что необходимо понять: регламентное задание и интерактивная обработка выполняются в разных условиях. Интерактивная обработка обычно запускается под пользователем с полными правами и в сеансе, где доступны контекстные данные формы. Регламентное задание выполняется на сервере, часто под системной учетной записью, которая может иметь ограниченный набор прав.
Основные причины сбоев:
Самая большая ошибка при написании регламентных заданий — отсутствие механизма отладки ошибок. Если транзакция отменяется, платформа просто выбрасывает исключение. Чтобы узнать, что именно пошло не так, необходимо использовать конструкцию Попытка...Исключение и записывать детальную информацию в журнал регистрации.
Рассмотрим пример того, как правильно обернуть код записи, чтобы увидеть реальную причину:
Попытка
Объект.Записать();
Исключение
ЗаписьЖурналаРегистрации("Ошибка записи документа",
УровеньЖурналаРегистрации.Ошибка,
Метаданные.Документы.ТвойДокумент,
Объект.Ссылка,
ОписаниеОшибки());
КонецПопытки;
Именно этот подход помог в обсуждаемом случае: автор добавил логирование и выяснил, что при записи документа не был заполнен критически важный реквизит («ключик»), который в интерактивной форме заполнялся автоматически.
Если код не проходит на сервере, проверьте пользователя, под которым запускается регламентное задание. Возможно, для этого пользователя в Настройках пользователей и прав установлена дата запрета редактирования. Также проанализируйте, не блокирует ли другой процесс документ в момент выполнения задания. В фоновом режиме вероятность возникновения конфликтов блокировок TLOCK гораздо выше из-за отсутствия пауз для пользователя.
Если вы уверены, что данные корректны, но срабатывают лишние проверки или подписки на события, которые мешают выполнению задания, можно воспользоваться свойством ОбменДанными.Загрузка. Этот метод позволяет платформе «понять», что данные загружаются, а не создаются пользователем вручную, что отключает ряд принудительных проверок.
Объект.ОбменДанными.Загрузка = Истина;
Объект.Записать();
Внимание: Используйте этот метод с осторожностью, так как он пропускает проверки бизнес-логики, которые могут быть важны для целостности данных.
Для глубокого анализа ситуации используйте Технологический журнал. Настройте его на события EXCP (исключения) и TLOCK (блокировки). Это позволит вам увидеть, в какой именно строке кода происходит сбой и какой объект системы препятствует выполнению транзакции.
Также всегда проверяйте, чтобы в модуле, отвечающем за регламентное задание, не вызывались никакие интерактивные функции, такие как Предупреждение, Вопрос или попытки обращения к ЭлементамФормы. Весь код должен быть реализован исключительно на серверных методах.
Соблюдая эти правила, вы сможете быстро локализовать проблему и обеспечить стабильную работу автоматических заданий в вашей системе.