Приложение 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.

Другие вопросы по тегам