SQL Native Client ODBC 应用程序在 SQLDisconnect 后未断开连接且未池化?

发布于 2024-07-10 08:09:19 字数 704 浏览 5 评论 0原文

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

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

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

问题:
以前有人见过这样的事情吗? 可能是什么原因造成的? 我最初的谷歌搜索并没有得到很好的结果!

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

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

Background:
I'm working with a program coded in C++ which uses ODBC on SQL Native Client to establish connections to interact with a SQL Server 2000 database.

Problem:
My connections are abstracted into an object which opens a connection when the object is instantiated and closes the connection when the object is destroyed. I can see that the objects are being destroyed: their destructor are firing and inside of these destructors, SQLDisconnect( ConnHandle ) is being called, followed by SQLFreeHandle( SQL_HANDLE_DBC, ConnHandle ); However, watching the connection count using sp_Who2 or the Performance Monitor in SQL shows the connection count increasing without relent, despite these connections being destroyed.

This hasn't proven problematic until executing a chain of functions that runs long enough to create several thousand of these objects and as such, several thousands of connections.

Question:
Has anyone seen anything like this before? What might be causing this? My initial google searches haven't proven very fruitful!

EDIT:
I have verified that SQLDisconnect is returning without error.

Connection pooling is off. In fact, when I attempt to enabling it using SQLSetEnvAttr, my application crashes when the 2nd call to SQLDriverConnect is made.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

尬尬 2024-07-17 08:09:19

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

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

有关如何检查 SQLDisconnect 错误的更多详细信息,请访问 MSDN

Check that you are not using connection pooling. If it is turned on, it will cache opened connections for some (configurable) time.

If you are not using connection pooling, then you must check return value of the SQLDisconnect(). You may have some transaction executing or rollbacking that wont let SQL Disconnect() release your connection.

You have more details on how to check for SQLDisconnect errors at MSDN.

潦草背影 2024-07-17 08:09:19

我相信我在使用 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

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

I believe I have seen the same issue in an application that uses MFC and ODBC, rather than the SQL native client API directly. Occaisonally my application hangs on shutdown, the stack trace is:

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

Try as I might, I cannot see anything that might cause such a hang. I'd be grateful if anyone can suggest a solution. It seems others have seen similar issues online, but to date I haven't found any solution.

我不咬妳我踢妳 2024-07-17 08:09:19
    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 内部调用有关。

    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

From your stacktrace not having a bottom, can we assume that the CDatabase is a global variable?
Possibly in a dll?

We found your exact symptoms if attempting disconnect from SQL Server from within the destructor of a global variable.

Using the MDAC ODBC drivers works successully.
Moving the code out of the destructor works sucessfully.

It seems something to do with sql native client not liking being called from inside a DllMain.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文