如何正确释放ODBC对象?

How to release ODBC objects correctly?

我创建了一个调用 SQLDriverConnect 的应用程序以连接到名为 'MyDB' 的 MS SQL 服务器数据库。做了一些事情后,它调用 SQLDisconnect.But 然后 SSMS 无法删除 'MyDB'。这意味着一些资源没有正确关闭。只有在退出进程后,SSMS 才会删除它( OS 释放它们)并且所有 SQLHENV 和 SQLHDBC 都被正确释放。 代码如下:

SMARTHSTMT::~SMARTHSTMT()
{
    if (!m_hstmt) return;
    SQLFreeStmt(m_hstmt, SQL_CLOSE);
    SQLFreeStmt(m_hstmt, SQL_UNBIND);
    SQLFreeStmt(m_hstmt, SQL_RESET_PARAMS);
    SQLFreeHandle(SQL_HANDLE_STMT, m_hstmt);
    m_hstmt = nullptr;
};

如何找到哪个对象没有被释放?我还应该考虑其他因素吗?任何想法或帮助表示赞赏。 编辑:断开连接的代码:

void AConnection::uDisconnect()
{
    if (m_hdbc)
    {
        SQLDisconnect(m_hdbc);
        SQLFreeHandle(SQL_HANDLE_DBC, m_hdbc);
        m_hdbc = nullptr;
    }
    if (m_henv)
    {
        SQLFreeHandle(SQL_HANDLE_ENV, m_henv);
        m_henv = nullptr;
    }
}

您可以检查是否 SQLDisconnect() returns SQL_ERROR。如果是这种情况,则语句可能仍处于打开状态,或者交易(如您检测到的那样)仍处于打开状态。

ODBC 中的事务处理(简化)如下:

默认情况下启用自动提交。一切都开始一个新的事务,如果语句成功,事务就会被提交。如果您没有更改提交模式,事务仍然打开让我很困惑。

如果您禁用了自动提交,则必须手动调用 SQLEndTrans(...) 以提交或回滚任何正在进行的事务。据我所知,ODBC 无法查询驱动程序是否有任何事务仍处于打开状态。

正如您提到对 SQLEndTrans() 的调用,我猜您已经禁用了自动提交。查看我的来源,我发现我总是在关闭连接句柄之前执行回滚 - 可能是因为同样的问题,我不记得确切(它的旧代码)。

无论如何,如果您启用了手动提交模式,我建议您在关闭连接句柄之前执行一次回滚。也许 SQL 服务器端会有工具来分析当时打开的内容的更多详细信息..

详情请看这里:https://msdn.microsoft.com/en-us/library/ms131281.aspx