背景
我正在使用C ++编写的程序,该程序在SQL Native Client上使用ODBC来建立与SQL Server 2000数据库交互的连接。
问题:
我的连接被抽象为一个对象,该对象在实例化对象时打开连接,并在对象被销毁时关闭连接。我可以看到对象被破坏:它们的析构函数正在触发,在这些析构函数内部,SQLDisconnect( ConnHandle )
被调用,然后是SQLFreeHandle( SQL_HANDLE_DBC, ConnHandle );
但是,使用sp_Who2
或者观察连接计数SQL中的性能监视器显示连接数增加而不会增加,尽管这些连接被破坏。
在执行一系列运行时间足以创建数千个这样的对象的函数链之前,这已经证明是有问题的,因此有数千个连接。
问题:
以前有人见过这样的事吗?可能是什么导致了这个?我最初的谷歌搜索没有证明非常有成效!
修改
我已经确认SQLDisconnect
没有错误地返回。
连接池已关闭。实际上,当我尝试使用SQLSetEnvAttr
启用它时,我的应用程序在第二次调用SQLDriverConnect
时崩溃。
答案 0 :(得分:2)
检查您是否使用了连接池。如果它已打开,它将缓存打开的连接一些(可配置的)时间。
如果您没有使用连接池,则必须检查SQLDisconnect()的返回值。您可能有一些事务执行或回滚,不会让SQL Disconnect()释放您的连接。
您有关于如何在MSDN检查SQLDisconnect错误的详细信息。
答案 1 :(得分:1)
我相信我在使用MFC和ODBC的应用程序中看到了同样的问题,而不是直接使用SQL本机客户端API。偶然我的应用程序在关闭时挂起,堆栈跟踪是:
sqlncli!CCriticalSectionNT::Enter sqlncli!SQLFreeStmt sqlncli!SQLFreeConnect sqlncli!SQLFreeHandle odbc32!UnloadDriver odbc32!FreeDbc odbc32!DestroyIDbc odbc32!FreeIdbc odbc32!SQLFreeConnect mfc42!CDatabase::Close mfc42!CDatabase::Free mfc42!CDatabase::~CDatabase
尽我所能,我看不到任何可能导致这种情况的事情。如果有人能提出解决方案,我将不胜感激。似乎其他人在网上看到了类似的问题,但到目前为止我还没有找到任何解决方案。
答案 2 :(得分:1)
sqlncli!CCriticalSectionNT::Enter sqlncli!SQLFreeStmt sqlncli!SQLFreeConnect sqlncli!SQLFreeHandle odbc32!UnloadDriver odbc32!FreeDbc odbc32!DestroyIDbc odbc32!FreeIdbc odbc32!SQLFreeConnect mfc42!CDatabase::Close mfc42!CDatabase::Free mfc42!CDatabase::~CDatabase
从没有底部的堆栈跟踪中,我们可以假设CDatabase是一个全局变量吗? 可能在一个DLL?
如果尝试从全局变量的析构函数中断开SQL Server,我们就会发现您的确切症状。
使用MDAC ODBC驱动程序可以成功运行。 将代码移出析构函数是成功的。
似乎与sql本地客户端无关,不喜欢从DllMain内部调用。