如何正确释放ODBC对象?

时间:2016-04-04 12:31:17

标签: sql-server odbc

我创建了一个调用SQLDriverConnect来连接到名为“MyDB”的MS SQL Server数据库的应用程序。做了一些事后,它调用了SQLDisconnect.But然后SSMS无法删除'MyDB'。这意味着某些资源未正确关闭。只有在退出进程后,SSMS才会删除它(操作系统释放它们),所有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;
    }
}

1 个答案:

答案 0 :(得分:0)

您可以检查SQLDisconnect()是否返回SQL_ERROR。如果是这种情况,则语句可能仍处于打开状态,或者事务(如您检测到的)仍处于打开状态。

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

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

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

当你提到对SQLEndTrans()的调用时,我猜你已经禁用了自动提交。看看我的来源,我看到我在关闭连接句柄之前总是做一个回滚 - 也许是因为同样的问题,我不记得确切(它的旧代码)。

无论如何,如果您启用了手动提交模式,我建议您在关闭连接句柄之前进行回滚。也许SQL Server端会有工具来分析当时完全打开的内容的更多细节。

请点击此处了解详情:https://msdn.microsoft.com/en-us/library/ms131281.aspx