Приложение ODBC для собственного клиента SQL не отключается после SQLDisconnect и не создает пул?
Фон:
Я работаю с программой, написанной на C++, которая использует ODBC для собственного клиента SQL для установления соединений для взаимодействия с базой данных SQL Server 2000.
Проблема:
Мои соединения абстрагируются в объект, который открывает соединение, когда создается объект, и закрывает соединение, когда объект уничтожается. Я вижу, что объекты разрушаются: их деструкторы стреляют, и внутри этих деструкторов, SQLDisconnect( ConnHandle )
вызывается, а затем SQLFreeHandle( SQL_HANDLE_DBC, ConnHandle );
Тем не менее, наблюдение за количеством соединений с помощью sp_Who2
или системный монитор в SQL показывает, что число подключений увеличивается без перерыва, несмотря на то, что эти подключения разрушаются.
Это не оказалось проблематичным до тех пор, пока не была выполнена цепочка функций, которая выполняется достаточно долго для создания нескольких тысяч таких объектов и, как таковых, нескольких тысяч соединений.
Вопрос:
Кто-нибудь видел что-нибудь подобное раньше? Что может быть причиной этого? Мои первые поиски в Google не оказались очень плодотворными!
РЕДАКТИРОВАТЬ:
Я подтвердил, что SQLDisconnect
возвращается без ошибок.
Пул подключений отключен. На самом деле, когда я пытаюсь включить его с помощью SQLSetEnvAttr
мое приложение вылетает при втором вызове SQLDriverConnect
сделан.
3 ответа
Убедитесь, что вы не используете пул соединений. Если он включен, он будет кэшировать открытые соединения в течение некоторого (настраиваемого) времени.
Если вы не используете пул соединений, вы должны проверить возвращаемое значение SQLDisconnect(). У вас может быть выполнение или откат транзакции, которая не позволяет SQL Disconnect () освободить ваше соединение.
У вас есть более подробная информация о том, как проверить наличие ошибок SQLDisconnect на MSDN.
Мне кажется, я видел ту же проблему в приложении, использующем MFC и ODBC, а не непосредственно клиентский API-интерфейс SQL. Иногда мое приложение зависает при завершении работы, трассировка стека:
SQLNCLI! CCriticalSectionNT:: Вход SQLNCLI!SQLFreeStmt SQLNCLI!SQLFreeConnect SQLNCLI!SQLFreeHandle odbc32! UnloadDriver odbc32! FreeDbc odbc32! DestroyIDbc odbc32! FreeIdbc odbc32!SQLFreeConnect mfc42! CDatabase:: Закрыть mfc42! CDatabase:: Free mfc42! CDatabase:: ~ CDatabase
Как ни старайся, я не вижу ничего, что могло бы вызвать такое зависание. Буду признателен, если кто-нибудь сможет предложить решение. Кажется, что другие видели подобные проблемы онлайн, но до настоящего времени я не нашел никакого решения.
SQLNCLI! CCriticalSectionNT:: Вход SQLNCLI!SQLFreeStmt SQLNCLI!SQLFreeConnect SQLNCLI!SQLFreeHandle odbc32! UnloadDriver odbc32! FreeDbc odbc32! DestroyIDbc odbc32! FreeIdbc odbc32!SQLFreeConnect mfc42! CDatabase:: Закрыть mfc42! CDatabase:: Free mfc42! CDatabase:: ~ CDatabase
Из вашей трассировки стека, не имеющей дна, мы можем предположить, что база данных CD является глобальной переменной? Возможно в DLL?
Мы нашли ваши точные симптомы, если пытались отключиться от SQL Server из деструктора глобальной переменной.
Использование драйверов MDAC ODBC работает успешно. Удаление кода из деструктора работает успешно.
Кажется, это связано с тем, что SQL-клиенту не нравится, когда его вызывают изнутри DllMain.