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