При разработке интеграционных решений в 1С часто возникает соблазн запустить фоновое задание непосредственно в подписке на событие ПриЗаписи или ПослеЗаписи. Однако такой подход приводит к ошибке Объект не найден. Давайте разберемся, почему это происходит и как выстроить архитектуру системы правильно.
Когда мы записываем элемент справочника, платформа открывает транзакцию СУБД. Пока эта транзакция не завершена (COMMIT не выполнен), данные объекта физически еще не записаны в базу данных — они находятся в «подвешенном» состоянии для других сеансов. В тот момент, когда мы из подписки запускаем фоновое задание, оно стартует в отдельном сеансе. Согласно уровням изоляции транзакций в базе данных, этот второй сеанс просто «не видит» еще не зафиксированных изменений в первом сеансе. Ссылка на объект существует в памяти, но обратиться к ней через запрос или метод ПолучитьОбъект() не удается, так как в базе данных этот объект еще «не родился».
Существует несколько подходов к решению этой задачи, от простых «заплаток» до архитектурно верных решений.
Это один из самых надежных методов. Вместо того чтобы сразу запускать «тяжелый» процесс, мы фиксируем факт необходимости отправки данных в специальном РегистрСведений. Этот регистр хранит ссылку на объект и статус обработки.
РегистрСведений, например, с названием ОчередьОбменов.ПослеЗаписи создаем запись в этот регистр.РегламентноеЗадание, которое работает по расписанию и считывает данные из регистра.Поскольку запись в регистр происходит в рамках той же транзакции, что и запись справочника, проблема «не найденного объекта» исключается полностью. Регламентное задание берет данные, которые уже гарантированно записаны в базу.
// Пример записи в очередь в подписке на событие
НаборЗаписей = РегистрыСведений.ОчередьОбменов.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Объект.Установить(Источник.Ссылка);
НоваяЗапись = НаборЗаписей.Добавить();
НоваяЗапись.Объект = Источник.Ссылка;
НоваяЗапись.Статус = Перечисления.СтатусыОчереди.КОбработке;
НаборЗаписей.Записать();
Если ваша задача — интеграция, то ПланОбмена является штатным и наиболее подходящим инструментом. Механизм регистрации изменений в ПланОбмена работает на уровне платформы.
Этот метод исключает риск «запуска ста тысяч фоновых заданий» при групповой обработке, так как очередь накапливается в системных таблицах и обрабатывается пакетно.
Рассмотрим риски такого подхода подробно:
rphost. При групповой перезаписи справочника из 10 000 элементов система попытается запустить 10 000 фоновых заданий, что приведет к падению сервера приложений.Для создания масштабируемой системы обмена данными необходимо придерживаться принципа асинхронной обработки:
Использование РегламентныеЗадания с очередью в РегистрСведений позволяет вам легко реализовывать повторные попытки (Retry) при возникновении ошибок обмена, что невозможно при мгновенном запуске фонового задания из подписки.