При разработке механизмов интеграции 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 секунд ожидания. Выясним, как это исправить.
Самый простой и эффективный способ — исключить стадию перебора протоколов. Если мы заранее знаем, что сервер принимает соединения через «Именованные каналы» (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.
Провайдер SQLOLEDB считается устаревшим. В современных системах рекомендуется использовать Microsoft OLE DB Driver for SQL Server (MSOLEDBSQL). Он обладает лучшей производительностью, поддерживает актуальные стандарты безопасности и более эффективно управляет пулом соединений.
Рассмотрим пример изменения строки соединения:
СтрокаСоединения = "Provider=MSOLEDBSQL; Data Source=""cortex""; Initial Catalog=""KA1""; Integrated Security=SSPI;";
Часто простая замена провайдера на более современный (при условии его установки на клиентском компьютере) устраняет задержки, связанные с устаревшими алгоритмами поиска серверов.
Если мы не можем изменить настройки сервера или строку соединения, можно вынести процесс открытия соединения в «фон», чтобы не блокировать интерфейс пользователя. Для этого в методе 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, и задержки не возникнет.
Если проблему нужно решить массово для всех приложений на конкретном сервере или клиенте без изменения кода 1С, воспользуемся системной утилитой Windows SQL Server Client Network Utility (вызывается через cliconfg.exe).
cliconfg.exe из командной строки.cortex).После этой настройки любое обращение через ADO к серверу cortex будет сразу использовать выбранный протокол, минуя стадию перебора.
Проанализируем еще несколько неочевидных причин задержки:
NetBIOS после неудачи с DNS. Попробуйте указать FQDN (полное имя домена, например, cortex.company.local) или IP-адрес.Подводя итог, можно сказать, что наиболее надежным решением является сочетание явного указания протокола в строке соединения и удержания соединения через глобальную переменную для использования встроенного механизма Connection Pooling.