Как устранить задержку при первом соединении через ADODB к SQL Server в 1С

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

При разработке механизмов интеграции 1С с внешними базами данных через COM-объекты часто возникает специфическая проблема: первое выполнение метода Open объекта ADODB.Connection занимает значительное время (обычно около 6–10 секунд), в то время как последующие вызовы отрабатывают мгновенно. Рассмотрим причины этого поведения и разберем способы оптимизации подключения.

Анализ причины задержки: почему возникает ожидание?

Разберем ситуацию, когда при первом обращении к SQL Server система «зависает» на несколько секунд. Основная причина кроется в механизме согласования протоколов (Protocol Negotiation). Провайдер SQLOLEDB по умолчанию настроен на перебор доступных протоколов передачи данных. Как правило, первым в списке идет TCP/IP. Если на стороне SQL Server этот протокол отключен (например, разрешены только Named Pipes) или существуют сетевые преграды для его использования, драйвер ожидает истечения таймаута попытки подключения по TCP, прежде чем переключиться на следующий доступный протокол.

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


Соединение = Новый COMОбъект("ADODB.Connection");
СтрокаСоединения = "Provider=SQLOLEDB; Data Source=""cortex""; Initial Catalog=""KA1""; User Id=""""; Password="""";Trusted_Connection=Yes";
Соединение.Open(СтрокаСоединения);

В данном случае, если сервер cortex не отвечает по 1433 порту (TCP), мы получаем те самые 6 секунд ожидания. Выясним, как это исправить.

Решение 1: Явное указание протокола в строке соединения

Самый простой и эффективный способ — исключить стадию перебора протоколов. Если мы заранее знаем, что сервер принимает соединения через «Именованные каналы» (Named Pipes), мы можем добавить соответствующий префикс к адресу сервера в параметре Data Source. Для протокола Named Pipes используется префикс np:, для TCP/IP — префикс tcp:.

Посмотрим на исправленный пример кода:


Соединение = Новый COMОбъект("ADODB.Connection");
// Указываем протокол явно через префикс np:
СтрокаСоединения = "Provider=SQLOLEDB; Data Source=""np:cortex""; Initial Catalog=""KA1""; Trusted_Connection=Yes";
Соединение.Open(СтрокаСоединения);

Использование np:cortex вместо простого cortex заставляет драйвер мгновенно использовать нужный транспорт, минуя попытки соединения по TCP.

Решение 2: Переход на современный провайдер данных

Провайдер SQLOLEDB считается устаревшим. В современных системах рекомендуется использовать Microsoft OLE DB Driver for SQL Server (MSOLEDBSQL). Он обладает лучшей производительностью, поддерживает актуальные стандарты безопасности и более эффективно управляет пулом соединений.

Рассмотрим пример изменения строки соединения:


СтрокаСоединения = "Provider=MSOLEDBSQL; Data Source=""cortex""; Initial Catalog=""KA1""; Integrated Security=SSPI;";

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

Решение 3: Асинхронная инициализация соединения

Если мы не можем изменить настройки сервера или строку соединения, можно вынести процесс открытия соединения в «фон», чтобы не блокировать интерфейс пользователя. Для этого в методе Open используется константа adAsyncConnect (значение 16).

Однако в 1С существует сложность: COM-объекты не пробрасывают события в платформу напрямую. Нам придется проверять состояние соединения в цикле или через обработчик ожидания, анализируя свойство State.

Разберем реализацию этого подхода:


// В модуле управляемого приложения или глобальном модуле
Перем ГлобальноеСоединение Экспорт;

Процедура ИнициализироватьПодключениеАсинхронно() Экспорт
    ГлобальноеСоединение = Новый COMОбъект("ADODB.Connection");
    СтрокаСоединения = "Provider=SQLOLEDB; Data Source=""cortex""; Initial Catalog=""KA1""; Trusted_Connection=Yes";
    // 16 - это adAsyncConnect
    ГлобальноеСоединение.Open(СтрокаСоединения, , , 16);
КонецПроцедуры

Функция ПодключениеГотово() Экспорт
    Если ГлобальноеСоединение = Неопределено Тогда
        Возврат Ложь;
    КонецЕсли;
    
    // State = 1 означает adStateOpen
    Возврат (ГлобальноеСоединение.State = 1);
КонецФункции

Использование глобальной переменной ГлобальноеСоединение позволяет сохранить объект активным. Пока пользователь открывает формы, соединение устанавливается в фоновом режиме. К моменту нажатия кнопки выполнения запроса State уже будет равен 1, и задержки не возникнет.

Решение 4: Глобальная настройка через cliconfg.exe

Если проблему нужно решить массово для всех приложений на конкретном сервере или клиенте без изменения кода 1С, воспользуемся системной утилитой Windows SQL Server Client Network Utility (вызывается через cliconfg.exe).

  1. Запустите cliconfg.exe из командной строки.
  2. Перейдите на вкладку Alias (Псевдонимы).
  3. Нажмите Add (Добавить).
  4. Введите имя сервера (например, cortex).
  5. Выберите нужный протокол (например, Named Pipes).
  6. Сохраните настройки.

После этой настройки любое обращение через ADO к серверу cortex будет сразу использовать выбранный протокол, минуя стадию перебора.

Дополнительные факторы, влияющие на скорость

Проанализируем еще несколько неочевидных причин задержки:

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

← На главную