4

背景:
我正在使用用 C++ 编写的程序,它使用 SQL Native Client 上的 ODBC 建立连接以与 SQL Server 2000 数据库进行交互。

问题:
我的连接被抽象为一个对象,当对象被实例化时打开连接,当对象被销毁时关闭连接。我可以看到对象正在被销毁:它们的析构函数正在触发并且在这些析构函数内部SQLDisconnect( ConnHandle )被调用,然后是SQLFreeHandle( SQL_HANDLE_DBC, ConnHandle ); 但是,使用sp_Who2SQL 中的性能监视器观察连接计数显示连接计数不断增加,尽管有这些连接被摧毁。

在执行运行足够长的函数链以创建数千个这样的对象并因此创建数千个连接之前,这并没有被证明是有问题的。

问:
有没有人见过这样的事情?这可能是什么原因造成的?我最初的谷歌搜索并没有证明很有成效!

编辑:
我已经验证SQLDisconnect返回没有错误。

连接池已关闭。事实上,当我尝试使用 启用它SQLSetEnvAttr时,我的应用程序在第二次调用时崩溃SQLDriverConnect

4

3 回答 3

2

检查您是否没有使用连接池。如果它打开,它将缓存打开的连接一段时间(可配置)。

如果不使用连接池,则必须检查 SQLDisconnect() 的返回值。您可能有一些事务正在执行或回滚,不会让 SQL Disconnect() 释放您的连接。

您可以在MSDN获得有关如何检查 SQLDisconnect 错误的更多详细信息。

于 2008-12-22T22:47:19.140 回答
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::关闭
mfc42!CDatabase::免费
mfc42!CDatabase::~CDatabase

尽我所能,我看不到任何可能导致这种挂起的东西。如果有人可以提出解决方案,我将不胜感激。似乎其他人在网上看到了类似的问题,但到目前为止我还没有找到任何解决方案。

于 2009-03-25T16:47:24.820 回答
1
    sqlncli!CCriticalSectionNT::Enter
    sqlncli!SQLFreeStmt
    sqlncli!SQLFreeConnect
    sqlncli!SQLFreeHandle
    odbc32!UnloadDriver
    odbc32!FreeDbc
    odbc32!DestroyIDbc
    odbc32!FreeIdbc
    odbc32!SQLFreeConnect
    mfc42!CDatabase::关闭
    mfc42!CDatabase::免费
    mfc42!CDatabase::~CDatabase

从您的堆栈跟踪没有底部,我们可以假设 CDatabase 是一个全局变量吗?可能在dll中?

如果尝试从全局变量的析构函数中断开与 SQL Server 的连接,我们发现了您的确切症状。

使用 MDAC ODBC 驱动程序成功。将代码移出析构函数可以成功。

这似乎与不喜欢从 DllMain 内部调用的 sql 本机客户端有关。

于 2012-04-17T01:33:02.750 回答