数据库为 oracle 6.0,使用 MFC ODBC,在析构时程序挂起,跟踪进去时发现在调用
::SQLDisconnect()一句时无法返回。程序架构:多线程,初始化时自己建立连接池,在读取数据库时使用CMyRecordset(派生自CRecordset)对象,并将其构造函数改为:
CPaperSet::CPaperSet(LPCSTR pszVolumeName, CDatabase* pdb)
: CRecordset(pdb)
{
//{{AFX_FIELD_INIT(CPaperSet)
m_PAPERNO = -1;
m_STEPFLAG = 0;
m_BTMTEAMNO = -1;
m_USERID_CUR = -1;
m_USERID_PREV = -1;
m_FORMAT = 0;
m_nFields = 7;
//}}AFX_FIELD_INIT
m_nDefaultType = snapshot;
    
    //数据连接统一分配,不允许私建,即不允许此处传入数据连接
    ASSERT(!pdb);
    ASSERT(pszVolumeName);    m_sVolumeName = pszVolumeName;
    //lpAccessor就是管理、分配CDatabase对象的类,其RequestConn()函数在互斥
    //后返回一个数据库连接
    m_pDatabase = lpAccessor->RequestConn(pszVolumeName);    //m_hstmt Alloced here will be fred by CRecordset::close().
    m_hstmt = SQL_NULL_HSTMT;
    if (m_pDatabase != NULL && m_pDatabase->IsOpen())
    {
        ASSERT_VALID(m_pDatabase);
        TRY
        {
            RETCODE nRetCode;
            AFX_SQL_SYNC(::SQLAllocStmt(m_pDatabase->m_hdbc, &m_hstmt));
            if (!Check(nRetCode))
                ThrowDBException(SQL_INVALID_HANDLE);
        }
        CATCH_ALL(e)
        {
            ASSERT(m_hstmt == SQL_NULL_HSTMT);
            do { e->Delete(); } while (0);
        }
        END_CATCH_ALL
    }
}在其析构函数中:
CPaperSet::~CPaperSet()
{
    if (IsOpen()) Close();    lpAccessor->ReleaseConn(m_sVolumeName);
}在数据集对象的使用上,只使用栈对象,确保锁释放、查询语句释放。