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

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

При разработке сложных автоматизированных рабочих мест (АРМ) перед программистом часто встает задача оптимизации трафика и нагрузки на базу данных. Когда сотрудники работают из разных точек мира, постоянное обновление тяжелых списков документов может приводить к задержкам. Логичным решением кажется кеширование данных на стороне клиента. Однако возникает критический вопрос: как обеспечить актуальность этого кеша, если документ был изменен или создан другим пользователем в другом сеансе? Разберем подробно, какие механизмы предоставляет платформа 1С:Предприятие 8.3 для решения этой задачи.

Решение 1: Использование возможностей Динамического списка

Прежде чем изобретать сложные системы оповещения, проанализируем стандартное поведение платформы. ДинамическийСписок — это мощный инструмент, который уже содержит встроенный механизм отслеживания изменений. Платформа автоматически рассылает служебные уведомления всем открытым динамическим спискам, если данные в основной таблице (например, Документ.РеализацияТоваровУслуг) изменились.

Рассмотрим по шагам, как это применить в кастомном АРМ:

  1. Если ваш АРМ построен на базе произвольных запросов или объектных моделей, вы можете добавить на форму скрытый динамический список.
  2. Настройте его на ту же основную таблицу, за которой нужно следить.
  3. Установите период обновления (в свойствах формы или списка). По умолчанию он составляет 60 секунд, но для оперативности его можно уменьшить до 10 секунд.
  4. В обработчике события списка или при обновлении данных формы (которое инициирует платформа) выполняйте обновление вашего кеша.

Этот метод хорош тем, что использует «родной» транспорт платформы и не требует написания сложного кода для передачи сигналов между сеансами.

Решение 2: Система взаимодействия (Native Push)

Если требуется реакция «секунда в секунду», наиболее современным и правильным подходом будет использование Системы взаимодействия. Это механизм, позволяющий сеансам обмениваться сообщениями напрямую через сервер взаимодействия.

Разберем алгоритм реализации:

  1. Создадим ПодпискаНаСобытие на запись нужных нам документов.
  2. В процедуре-обработчике подписки на стороне сервера будем отправлять программное сообщение.

Пример серверного кода в подписке:


Процедура ПриЗаписиДокументаДляОповещения(Источник, Отказ) Экспорт
    Если Отказ Тогда Возврат; КонецЕсли;
    
    ПараметрыСообщения = СистемаВзаимодействия.СоздатьСообщение(ИдентификаторОбсуждения);
    ПараметрыСообщения.Текст = "ОбновитьДанные";
    ПараметрыСообщения.Данные = Источник.Ссылка;
    ПараметрыСообщения.Записать();
КонецПроцедуры

На стороне клиента в форме АРМ мы подключаем обработчик:


&НаКлиенте
Процедура ПриОткрытии(Отказ)
    СистемаВзаимодействия.ПодключитьОбработчикОповещения(Новый ОписаниеОповещения("ОбработкаСообщенияСистемыВзаимодействия", ЭтотОбъект));
КонецПроцедуры

&НаКлиенте
Процедура ОбработкаСообщенияСистемыВзаимодействия(Сообщение, ДополнительныеПараметры) Экспорт
    Если Сообщение.Текст = "ОбновитьДанные" Тогда
        ОбновитьЛокальныйКеш(Сообщение.Данные);
    КонецЕсли;
КонецПроцедуры

Этот метод практически не нагружает базу данных, так как сигнал проходит через отдельный сервис взаимодействия, минуя основные таблицы БД.

Решение 3: Метод глобального штампа времени

Выясним причину, по которой постоянные запросы к БД считаются тяжелыми. Обычно это связано с объемом передаваемых данных. Мы можем оптимизировать этот процесс, внедрив стратегию «легкого опроса».

Проанализируем ситуацию: нам не нужно знать, что именно изменилось, пока мы не убедимся, что изменения вообще были. Для этого используется «Глобальный штамп»:

  1. Создаем Константа.ВерсияДанныхАРМ (тип Число или УникальныйИдентификатор).
  2. В ПодпискаНаСобытие при записи любого документа увеличиваем это число или генерируем новый Новый УникальныйИдентификатор().
  3. В форме АРМ запускаем ПодключитьОбработчикОжидания с интервалом, например, 5 секунд.
  4. Внутри обработчика выполняется сверхлегкий запрос: Выбрать Значение ИЗ Константы.ВерсияДанныхАРМ.

Пример реализации проверки:


&НаКлиенте
Процедура ПроверитьОбновленияНаСервере()
    ТекущаяВерсияНаСервере = ПолучитьВерсиюДанныхИзКонстанты(); // Вызов серверной функции
    Если ТекущаяВерсияНаСервере <> ЭтаФорма.ЛокальнаяВерсияДанных Тогда
        ЭтаФорма.ЛокальнаяВерсияДанных = ТекущаяВерсияНаСервере;
        ОбновитьСписокДокументов(); // Тяжелый запрос выполняется только здесь
    КонецЕсли;
КонецПроцедуры

Преимущество: Даже если в базе работают 100 пользователей, запрос одной константы раз в 5 секунд создаст ничтожную нагрузку по сравнению с полным обновлением списка документов.

Решение 4: Регистр сведений и фоновые задания

Если стоит задача не просто обновить список, а передать конкретные изменения (дельту), можно использовать РегистрСведений как очередь сообщений.

Рассмотрим шаги реализации:

  1. Создаем непериодический РегистрСведений.ОчередьИзмененийДляАРМ с измерениями Пользователь и Документ.
  2. В подписке на событие при записи документа определяем список активных пользователей (используя ПолучитьСеансыИнформационнойБазы()) и записываем для каждого из них строку в регистр.
  3. На клиенте в АРМ обработчик ожидания проверяет наличие записей в этом регистре именно для текущего пользователя.
  4. После обработки изменений клиент удаляет свои записи из регистра, чтобы не обрабатывать их повторно.

Этот метод является более трудоемким в реализации (нужно следить за очисткой регистра и активностью сеансов), но он позволяет передавать точечные изменения без повторного перечитывания всей таблицы документов.

Решение 5: Внешние брокеры (для высоконагруженных систем)

В исключительных случаях, когда количество сеансов исчисляется сотнями, а база данных критично относится к любым дополнительным запросам, можно рассмотреть использование внешних брокеров сообщений, таких как MQTT или RabbitMQ.

В этом сценарии 1С через HTTPЗапрос или внешнюю компоненту сообщает брокеру об изменении. На стороне клиента АРМ работает внешняя компонента, которая поддерживает постоянное TCP-соединение с брокером и генерирует ВнешнееСобытие в момент прихода сигнала. Это позволяет реализовать полноценную Push-архитектуру, полностью освободив 1С от необходимости периодических опросов базы данных (polling).

Резюме

Выбор конкретного метода зависит от ваших ресурсов и требований к скорости:

← На главную