在程序中开了两个线程,都会调用下列代码连接oracle数据库,如果数据库连接失败,那么会每秒钟重新连接一次,可是在重连过程中,发现有时这两个线程调用DBConnection->Open()时会被阻塞,不再往下执行,也不返回;
而且在重连过程中,有时会返回错误“灾难性故障(0x8000ffff)”,之后一个循环再连接数据库时线程就会阻塞在同样的位置,而且CPU占用率是100%,这是为什么?       ::CoInitialize(NULL);

_ConnectionPtr DBConnection;        char bstrName[256];
        sprintf(bstrName,"Provider=OraOLEDB.Oracle.1;Data Source=%s;User Id=%s;Password=%s;",
DataSource,UserID,Password);
try
{
//打开数据库:
HRESULT   hr = DBConnection.CreateInstance(__uuidof(Connection)); if(SUCCEEDED(hr))
{ // DBConnection->put_ConnectionTimeout(long(5));
// DBConnection->put_CommandTimeout(long(5));
hr = DBConnection->Open(bstrName, "" ,"" , adConnectUnspecified/*adAsyncConnect*/); if(SUCCEEDED(hr))
{ }
else
{

}
}
else
{

}
}
catch(_com_error &e)
{
DWORD errorCode = e.Error(); //e.WCode();
str=e.ErrorMessage();
}

解决方案 »

  1.   

    智能指针最后释放了没有??
    最后要:
    DBConnection->Close();
    DBConnection = NULL;
    CoUninitialize();
      

  2.   

    DBConnection->Open()返回成功才需要释放,如果连接不成功是不需要释放的
      

  3.   

    你是连接不成功,反复Open的时候报错??
      

  4.   

    Open方法有个参数为同步、异步而且可以设置Timeout
      

  5.   

    是的,用DBConnection->put_ConnectionTimeout(long(5)); DBConnection->put_CommandTimeout(long(5));
    都试过了,但是没有用啊,还是不会返回;而且用 adAsyncConnect参数的话会报“runtime error”的错误
      

  6.   

    oracle本身会有连接超时的异常啊,可以被ADO catch到..
    你可以在catch(_com_error &e)代码段中进行超时处理...
      

  7.   

    但问题是线程阻塞在DBConnection->Open(),根本不往下执行了,是什么问题也Catch不到
      

  8.   

    我这里20,30秒的样子还是会被catch到,抛出异常:"ORA-12170: TNS: 连接超时"设置ConnectionTimeout没用,因为这是指定中止一个失败的Connection.Open方法调用之前必须等待的时间.. 让Open认为连接失败,估计要等到oracle抛出上面的异常才行..所以,你可以试试其它的办法:比如自己定义一个定时器,时间到了另外进行连接..