Как ускорить запись контрагента в 1С при отправке почтовых уведомлений?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке подписок на события часто возникает архитектурная ошибка: интеграционные и сетевые действия (отправка писем по протоколу SMTP, вызовы HTTP-сервисов, обращение к внешним API) выполняются непосредственно в обработчике события ПриЗаписи. Разберем, почему синхронная отправка писем замедляет работу пользователей, какие риски она несет для базы данных и как реализовать надежную асинхронную схему обработки.

В чем заключается архитектурная проблема синхронной отправки?

Проанализируем механику работы платформы 1С:Предприятие при записи ссылочного объекта. Обработчик подписки на событие ПриЗаписи выполняется строго внутри транзакции записи базы данных. Это порождает сразу несколько критических проблем:

  1. Блокировка интерфейса: объект ИнтернетПочтовыйПрофиль по умолчанию использует таймаут подключения до 30–60 секунд. Если SMTP-сервер недоступен, происходят потери пакетов или возникают проблемы с DNS, пользовательский сеанс зависает на все время ожидания сетевого ответа.
  2. Эскалация блокировок СУБД: пока длится транзакция и соединение с почтовым сервером, на уровне СУБД удерживаются монопольные транзакционные блокировки на запись контрагента и связанные таблицы. Другие пользователи, пытающиеся прочитать или изменить эти данные, переходят в режим ожидания, что может приводить к ошибкам ожидания блокировки данных и взаимоблокировкам (deadlock).
  3. Откат записи при сбое сети: если при отправке письма возникнет сетевая ошибка или исключение, транзакция записи будет отменена целиком, и изменения по контрагенту не сохранятся в базе.

Решение 1: Буферизация через регистр сведений «Очередь сообщений»

Рассмотрим классический и наиболее надежный способ разделения транзакционной логики и сетевых вызовов — создание очереди исходящих сообщений с отложенной обработкой регламентным или фоновым заданием.

Разберем по шагам, как устроен этот механизм:

  1. Создаем непериодический независимый регистр сведений ОчередьИсходящихПисем с измерениями Идентификатор (тип УникальныйИдентификатор), ресурсами Тема, АдресПолучателя, ТекстПисьма, ДатаСоздания и реквизитом КоличествоПопыток.
  2. В подписке на событие ПриЗаписи формируем текст и параметры письма, но не выполняем сетевой отправки, а быстро фиксируем запись в регистре сведений. Запись в регистр происходит за доли миллисекунды в той же транзакции.
  3. Создаем регламентное задание с отдельной процедурой отправки, которая считывает порцию неотправленных записей из регистра, выполняет отправку и удаляет успешно отправленные строки (либо переводит статус в «Отправлено»).

Посмотрим на пример заполнения очереди в обработчике события:


Процедура КонтрагентыПриЗаписи(Источник, Отказ) Экспорт
    Если Источник.ОбменДанными.Загрузка Тогда
        Возврат;
    КонецЕсли;
    
    // Формируем запись в регистр очереди
    МенеджерЗаписи = РегистрыСведений.ОчередьИсходящихПисем.СоздатьМенеджерЗаписи();
    МенеджерЗаписи.Идентификатор = Новый УникальныйИдентификатор();
    МенеджерЗаписи.АдресПолучателя = "control@example.com";
    МенеджерЗаписи.Тема = "Изменен контрагент: " + СокрЛП(Источник.Наименование);
    МенеджерЗаписи.ТекстПисьма = "Пользователь обновил данные контрагента " + Источник.Наименование;
    МенеджерЗаписи.ДатаСоздания = ТекущаяДатаСеанса();
    МенеджерЗаписи.Записать();
КонецПроцедуры

Решение 2: Использование подсистем Библиотеки Стандартных Подсистем (БСП)

Если конфигурация разработана на основе БСП, писать кастомные регистры и механизмы не требуется. Рассмотрим встроенные средства, решающие задачу «из коробки»:

  1. Документ «Электронное письмо исходящее»: вместо работы напрямую с низкоуровневыми объектами ИнтернетПочта создается документ ЭлектронноеПисьмоИсходящее в статусе «Черновик» или «К отправке». Встроенное регламентное задание ОтправкаПолучениеПочты автоматически отправляет накопленные письма в фоновом режиме, ведет логирование попыток и фиксирует дату фактической отправки.
  2. Подсистема «Очередь заданий»: позволяет добавить вызов экспортной процедуры в фоновую очередь без создания ссылочных документов. Подсистема сама следит за расписанием, количеством повторов при сбоях и обработкой исключений.
  3. Версионирование объектов: если отправка писем служила исключительно целям аудита действий пользователей (кто и что изменил в карточке), эффективнее включить типовую подсистему «Версионирование объектов» БСП. Это избавит сотрудников от потока однотипных писем и предоставит наглядный отчет об изменениях реквизитов прямо в форме контрагента.

Решение 3: Немедленный фоновый запуск (асинхронная отправка без задержки формы)

Если уведомление должно уйти не по расписанию регламентного задания раз в минуту, а сразу же, можно запустить фоновый поток платформы. Вызов фонового задания выполняется вне транзакции (например, в обработчике формы ПослеЗаписиНаСервере или через вызов процедуры общего модуля):


ПараметрыПроцедуры = Новый Структура;
ПараметрыПроцедуры.Вставить("КонтрагентСсылка", КонтрагентОбъект.Ссылка);

ПараметрыЗадания = Новый Массив;
ПараметрыЗадания.Добавить(ПараметрыПроцедуры);

ФоновыеЗадания.Выполнить("ИнтеграцияПочта.ОтправитьУведомлениеФон", ПараметрыЗадания);

При таком подходе транзакция завершается мгновенно, форма контрагента закрывается без задержек, а сетевой стек 1С взаимодействует с почтовым сервером в изолированном фоновом сеансе.

Решение 4: Решение проблем с сетевой инфраструктурой и DNS

Проанализируем системные причины медленного SMTP-соединения. Если подключение к почтовому серверу занимает более 1–2 секунд, необходимо проверить следующие факторы:

  1. Reverse DNS (PTR-записи): некоторые корпоративные SMTP-серверы при входящем подключении пытаются выполнить обратное DNS-резолвирование IP-адреса клиента. Если локальный DNS-сервер настроен некорректно или не отвечает, соединение «зависает» на время DNS-таймаута. Отключение проверки обратной зоны на почтовом сервере или прописывание серверов в локальный файл hosts решает проблему.
  2. Локальный почтовый релей (Local Smart Host): рекомендуется развернуть легковесный почтовый сервис (например, Postfix) непосредственно на сервере 1С или внутри локального контура. Платформа 1С передает письмо локальному релею за миллисекунды по 127.0.0.1 без использования внешнего интернета, а релей самостоятельно организует повторные попытки доставки при сбоях внешнего канала.
← На главную