При регулярном обмене данными с множеством информационных баз 1С разработчики сталкиваются с заметными задержками при инициализации внешних подключений. Инициализация COM-соединения через V83.COMConnector к каждой отдельной базе может занимать от 10 до 20 секунд. Возникает закономерный вопрос: можно ли единожды получить COM-объект подключения к удаленной базе, сохранить его в базе данных, файле или хранилище настроек и затем мгновенно переиспользовать в следующих сеансах?
Разберем детально технические ограничения платформы 1С, поведение COM-объектов в памяти, особенности лицензирования и правильные способы оптимизации взаимодействия между базами.
Проанализируем природу COM-объекта в операционной системе и платформе 1С. Объект подключения, возвращаемый методом Connect(), не содержит в себе копию удаленной базы данных. Он представляет собой неуправляемый системный указатель в оперативной памяти текущего процесса на интерфейс IDispatch / IUnknown библиотеки COM-соединения.
Попытки сохранить такой объект через стандартные механизмы сериализации платформы приводят к ошибкам или потере данных по следующим причинам:
ЗначениеВФайл(), ни ЗначениеВСтрокуВнутр(), ни объект СериализаторXDTO, ни стандартные функции СохранитьЗначение() не способны сохранить живое межпроцессное или сетевое соединение на диск.rphost) адресное пространство уничтожается. Даже если бы существовал способ записать байты указателя в файл, при чтении в новом процессе этот адрес указывал бы в пустоту или на чужие данные в памяти.Рассмотрим попытку удержать объект соединения во временном хранилище платформы 1С. Поместив COM-объект во временное хранилище с помощью ПоместитьВоВременноеХранилище(), разработчик лишь сохраняет ссылку на объект в оперативной памяти сервера на время текущего сеанса.
Однако здесь действуют строгие системные правила работы с кэшем временного хранилища:
Важнейшим скрытым фактором при удержании соединений является механизм лицензирования 1С. Проанализируем, как расходуются лицензии:
Таким образом, попытка держать открытые подключения приводит к быстрому исчерпанию пула серверных лицензий и блокировке работы пользователей.
Если задача требует удерживать соединение в рамках одного серверного сеанса без использования временного хранилища, рекомендуется использовать общий модуль с повторным использованием возвращаемых значений.
Посмотрим на пример организации функции в общем модуле со свойством Повторное использование возвращаемых значений на время сеанса:
Функция ПолучитьCOMСоединениеКБазе(СтрокаПодключения) Экспорт
COMКоннектор = Новый COMОбъект("V83.COMConnector");
Попытка
Возврат COMКоннектор.Connect(СтрокаПодключения);
Исключение
ЗаписьЖурналаРегистрации("COM-Соединение", УровеньЖурналаРегистрации.Ошибка,,,
"Не удалось подключиться к базе: " + ОписаниеОшибки());
Возврат Неопределено;
КонецПопытки;
КонецФункции
При вызове такой функции с одинаковой строкой подключения платформа вернет уже созданный в текущем сеансе объект без повторной авторизации. Однако после завершения сеанса соединение будет закрыто автоматически.
Объект V83.COMConnector предоставляет встроенный механизм пула соединений, который управляется свойствами самого коннектора. Разберем доступные параметры пула:
PoolCapacity — максимальное количество неиспользуемых соединений, удерживаемых в пуле.PoolTimeout — время (в секундах), в течение которого свободное соединение остается в пуле перед его автоматическим закрытием.MaxServerConnections — предельное количество одновременно открытых соединений с сервером.Посмотрим, как настраивается пул соединений перед вызовом:
Коннектор = Новый COMОбъект("V83.COMConnector");
Коннектор.PoolCapacity = 10;
Коннектор.PoolTimeout = 60; // удержание соединения в течение 60 секунд
Коннектор.MaxServerConnections = 20;
Соединение = Коннектор.Connect(СтрокаПодключения);
// Выполнение необходимых операций выборки данных
// ...
// Явное освобождение переменной для возврата в пул
Соединение = Неопределено;
При повторном вызове метода Connect() с теми же параметрами в течение интервала PoolTimeout платформа мгновенно возьмет готовое соединение из пула без накладных расходов на создание сеанса.
Для регулярного обмена с большим количеством баз (десятки узлов) использование COM-технологии архитектурно устарело. Рассмотрим более эффективные и современные альтернативы:
ФоновыеЗадания. Запуск нескольких параллельных потоков сокращает общее время ожидания с нескольких минут до нескольких секунд.