Как загрузить справочник из XML в 1С без долгого цикла и оптимизировать обмен

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

При интеграции систем через веб-сервисы критически важна скорость работы. Программисты часто сталкиваются с задачей быстрой передачи элементов справочника из одной базы 1С в другую. В таблицах значений мы привыкли использовать методы вроде Загрузить(), которые мгновенно заполняют данные в памяти. Однако со справочниками такой подход не работает.

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

Ограничения платформы и причины медленной загрузки

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

В объектной модели 1С отсутствует метод одномоментной массовой выгрузки и загрузки таблицы справочника из внешнего файла. Запись любого элемента должна производиться индивидуально вызовом метода Записать().

Основные факторы, снижающие скорость пообъектной загрузки:

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

Способ 1. Оптимизация пообъектной записи элементов

Если отказаться от структуры справочника нельзя, разберем по шагам, как максимально ускорить его загрузку из XML.

1. Отключение проверок через режим загрузки обмена

Установка свойства ОбменДанными.Загрузка = Истина перед записью объекта отключает стандартные проверки платформы, а также выполнение бизнес-логики в модулях объекта и подписках на события. Это существенно ускоряет сохранение в СУБД.

2. Использование явных транзакций

По умолчанию каждый вызов Записать() открывает отдельную транзакцию СУБД, что создает колоссальную нагрузку на диск. Объединение группы записей в одну общую транзакцию ускоряет процедуру в разы.

Посмотрим на пример кода оптимизированной загрузки с использованием СериализаторXDTO и ЧтениеXML:


ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(ПутьКФайлуXML);

НачатьТранзакцию();

Попытка
    Пока ЧтениеXML.Прочитать() Цикл
        Если ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента И ЧтениеXML.Имя = "CatalogObject.Товары" Тогда
            ЭлементСправочника = СериализаторXDTO.ПрочитатьXML(ЧтениеXML);
            
            // Отключаем обработчики и проверки
            ЭлементСправочника.ОбменДанными.Загрузка = Истина;
            
            ЭлементСправочника.Записать();
        КонецЕсли;
    КонецЦикла;
    
    ЗафиксироватьТранзакцию();
Исключение
    ОтменитьТранзакцию();
    ЧтениеXML.Закрыть();
    ВызватьИсключение;
КонецПопытки;

ЧтениеXML.Закрыть();

3. Управление полнотекстовым поиском

На время выполнения массовой загрузки целесообразно отключать индексацию полнотекстового поиска вызовом метода ПолнотекстовыйПоиск.УстановитьРежимУправленияПолнотекстовымПоиском(). После завершения операции режим индексации возвращается в исходное состояние.

Способ 2. Замена справочника на регистр сведений

Если данные в приемнике предназначены исключительно для чтения и не используются в качестве ссылок в других документах или журналах, оптимальным решением станет изменение структуры метаданных.

В отличие от справочников, регистры сведений позволяют записывать данные не пообъектно, а целыми наборами записей (с флагом Замещать = Истина). Запись набора записей регистров сведений в платформе 1С выполняется мгновенно.

Рассмотрим пример загрузки набора записей регистра из XML:


ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(ПутьКФайлуXML);

НаборЗаписей = СериализаторXDTO.ПрочитатьXML(ЧтениеXML);

Если ТипЗнч(НаборЗаписей) = Тип("РегистрСведенийНаборЗаписей.КэшСправочника") Тогда
    // Замещаем все существующие данные в регистре одним вызовом
    НаборЗаписей.Записать(Истина); 
КонецЕсли;

ЧтениеXML.Закрыть();

Способ 3. Переход на инкрементальный (дельта) обмен

Схема с полной очисткой таблицы и полной перезагрузкой всех элементов при каждом веб-запросе неизбежно приведет к сбоям по мере роста объема данных. Для достижения высоких показателей скорости в 1–2 секунды рекомендуется изменить подход к обмену:

  1. Использование планов обмена: регистрируйте изменения справочника на стороне источника (объект ПланОбмена).
  2. Передача только изменений: при вызове веб-сервиса выгружайте в XML не весь справочник, а только созданные или отредактированные элементы с момента последнего сеанса.
  3. Оптимизация формата: для передачи данных через веб-сервисы эффективнее применять формат JSON или использовать сжатие данных (ZIP, FastInfoSet), что ускоряет десериализацию текста на сервере-приемнике.
← На главную