При разработке сложных автоматизированных рабочих мест (АРМ) перед программистом часто встает задача оптимизации трафика и нагрузки на базу данных. Когда сотрудники работают из разных точек мира, постоянное обновление тяжелых списков документов может приводить к задержкам. Логичным решением кажется кеширование данных на стороне клиента. Однако возникает критический вопрос: как обеспечить актуальность этого кеша, если документ был изменен или создан другим пользователем в другом сеансе? Разберем подробно, какие механизмы предоставляет платформа 1С:Предприятие 8.3 для решения этой задачи.
Прежде чем изобретать сложные системы оповещения, проанализируем стандартное поведение платформы. ДинамическийСписок — это мощный инструмент, который уже содержит встроенный механизм отслеживания изменений. Платформа автоматически рассылает служебные уведомления всем открытым динамическим спискам, если данные в основной таблице (например, Документ.РеализацияТоваровУслуг) изменились.
Рассмотрим по шагам, как это применить в кастомном АРМ:
Этот метод хорош тем, что использует «родной» транспорт платформы и не требует написания сложного кода для передачи сигналов между сеансами.
Если требуется реакция «секунда в секунду», наиболее современным и правильным подходом будет использование Системы взаимодействия. Это механизм, позволяющий сеансам обмениваться сообщениями напрямую через сервер взаимодействия.
Разберем алгоритм реализации:
ПодпискаНаСобытие на запись нужных нам документов.Пример серверного кода в подписке:
Процедура ПриЗаписиДокументаДляОповещения(Источник, Отказ) Экспорт
Если Отказ Тогда Возврат; КонецЕсли;
ПараметрыСообщения = СистемаВзаимодействия.СоздатьСообщение(ИдентификаторОбсуждения);
ПараметрыСообщения.Текст = "ОбновитьДанные";
ПараметрыСообщения.Данные = Источник.Ссылка;
ПараметрыСообщения.Записать();
КонецПроцедуры
На стороне клиента в форме АРМ мы подключаем обработчик:
&НаКлиенте
Процедура ПриОткрытии(Отказ)
СистемаВзаимодействия.ПодключитьОбработчикОповещения(Новый ОписаниеОповещения("ОбработкаСообщенияСистемыВзаимодействия", ЭтотОбъект));
КонецПроцедуры
&НаКлиенте
Процедура ОбработкаСообщенияСистемыВзаимодействия(Сообщение, ДополнительныеПараметры) Экспорт
Если Сообщение.Текст = "ОбновитьДанные" Тогда
ОбновитьЛокальныйКеш(Сообщение.Данные);
КонецЕсли;
КонецПроцедуры
Этот метод практически не нагружает базу данных, так как сигнал проходит через отдельный сервис взаимодействия, минуя основные таблицы БД.
Выясним причину, по которой постоянные запросы к БД считаются тяжелыми. Обычно это связано с объемом передаваемых данных. Мы можем оптимизировать этот процесс, внедрив стратегию «легкого опроса».
Проанализируем ситуацию: нам не нужно знать, что именно изменилось, пока мы не убедимся, что изменения вообще были. Для этого используется «Глобальный штамп»:
Константа.ВерсияДанныхАРМ (тип Число или УникальныйИдентификатор).ПодпискаНаСобытие при записи любого документа увеличиваем это число или генерируем новый Новый УникальныйИдентификатор().ПодключитьОбработчикОжидания с интервалом, например, 5 секунд.Выбрать Значение ИЗ Константы.ВерсияДанныхАРМ.Пример реализации проверки:
&НаКлиенте
Процедура ПроверитьОбновленияНаСервере()
ТекущаяВерсияНаСервере = ПолучитьВерсиюДанныхИзКонстанты(); // Вызов серверной функции
Если ТекущаяВерсияНаСервере <> ЭтаФорма.ЛокальнаяВерсияДанных Тогда
ЭтаФорма.ЛокальнаяВерсияДанных = ТекущаяВерсияНаСервере;
ОбновитьСписокДокументов(); // Тяжелый запрос выполняется только здесь
КонецЕсли;
КонецПроцедуры
Преимущество: Даже если в базе работают 100 пользователей, запрос одной константы раз в 5 секунд создаст ничтожную нагрузку по сравнению с полным обновлением списка документов.
Если стоит задача не просто обновить список, а передать конкретные изменения (дельту), можно использовать РегистрСведений как очередь сообщений.
Рассмотрим шаги реализации:
РегистрСведений.ОчередьИзмененийДляАРМ с измерениями Пользователь и Документ.ПолучитьСеансыИнформационнойБазы()) и записываем для каждого из них строку в регистр.Этот метод является более трудоемким в реализации (нужно следить за очисткой регистра и активностью сеансов), но он позволяет передавать точечные изменения без повторного перечитывания всей таблицы документов.
В исключительных случаях, когда количество сеансов исчисляется сотнями, а база данных критично относится к любым дополнительным запросам, можно рассмотреть использование внешних брокеров сообщений, таких как MQTT или RabbitMQ.
В этом сценарии 1С через HTTPЗапрос или внешнюю компоненту сообщает брокеру об изменении. На стороне клиента АРМ работает внешняя компонента, которая поддерживает постоянное TCP-соединение с брокером и генерирует ВнешнееСобытие в момент прихода сигнала. Это позволяет реализовать полноценную Push-архитектуру, полностью освободив 1С от необходимости периодических опросов базы данных (polling).
Выбор конкретного метода зависит от ваших ресурсов и требований к скорости:
1С:Предприятие 8.3 оптимальным выбором является Система взаимодействия.