老问题,还没找到解决办法。vc 使用ado 连接oracle 数据库。
程序启动连接正常。
之后把网线拔掉,但是m_Connection-> Close();
m_Connection-> Open((LPCTSTR)   ConnectStr,   (LPCTSTR)   0,   (LPCTSTR)   0,   adConnectUnspecified);   //这句没Open仍然成功。
按道理这里Open应该返回失败才对。插上网线,Open也是成功,但是Open成功的Connect却不能查询数据库。这个帖子:
http://topic.csdn.net/u/20070924/21/8076067a-71a0-4200-8e65-66925641a309.html
已经讨论了很多,可是还是没有找到解决的办法。

解决方案 »

  1.   

    拔掉网线后,代码里用一个新的
    _ConnectionPtr创建ado连接对象pConnTemp,
    pConnTemp->Open(...)试试。如果还好用那就迷茫了。
      

  2.   

    断开网线后,连接数据库,如果open成功,那么后续执行数据库读取等操作应该就会失败了,失败后,再尝试open数据库试试...就知道网络断开了
      

  3.   

    1. 反汇编,看看是不是编译器优化造成的。
    2. 也许是ado的bug。Windows都有bug,ado有bug也不奇怪。不影响安全性、不严重的bug, MS很可能就不改了。
      

  4.   

    ADO本来就有这么一个算是Bug的东西,没办法的,这种情况我见多了解决方法就是Open前查看与服务器IP是否连通判断下,然后Connect,做ADO操作
      

  5.   

    呵呵,这是肯定的,ado,connection,对象是不会得到网络的物理断连得真实情况。不过可以使用服务端游标的链接对象来检测,也许还能稍微准确些。只是服务端游标在某些场合下不适合查询。pconn->CursorLocation   =   adUseServer;使用两种游标类型的链接对象,服务端仅仅用来检测数据库物理连接的通断情况,并适时的通知数据库处理线程关闭并放弃客户端游标连接对象。直至服务端游标的链接对象能够重新成功的链接数据库。客户端游标链接对象用于正常的查询数据库的操作。
    这是解决方案之一。另外的方案,就是用检测线程在应用意义上的去检测到数据库的物理链路是否畅通,socket,connect 1433端口
      

  6.   

    ADO是有连接缓冲池的,
    当你连接之后,关掉再次连接.
    其实ADO跟本没有再连接,而是从缓存池里找一个可用的连接.
    所以就会出现上面的情况.如果你时间等久一点2分钟之后,再连接就会出错了(因为连接池回间隔一段时间之后去查询连接是否可用)
      

  7.   

    这里的物理链路中断是说以下两种情况,和通常所说的网络的物理连接中断不完全相同。 1。数据库服务器服务停止, 
    2。与数据库服务器之间的网络发生中断 以下异常发生在如上两种情况。 首先会捕获到如下异常,此异常是在我周期性使用select查询时,发生了如上两种情况。 
    此异常可判断为到数据库服务器的连接发生中断 
    Error   number:   80004005 
    [DBNETLIB][ConnectionWrite   (send()).]一般性网络错误。请检查网络文档。 
    SQLState   :   08S0   
    NativeError   :   b 接下来,pConn-> Close,并重新Open连接会发生如下异常,此异常是重新连接时抛出的。此时可判断为到远程服务器的连接完全中断 Error   number:   80004005 
    [DBNETLIB][ConnectionOpen   (Connect()).]SQL   Server   不存在或拒绝访问。 
    SQLState   :   08001 
    NativeError   :   11 处理这个问题,可以在捕获以上异常之后,不断地进行pConn-> Open....,这里我纠正一下自己的一个错误,我曾经提到的要释放之前Connection实例,并重新CreateInstance,其实这种情况可以无需这样做,仅仅需要关闭发生异常的链接对象,然后重新Open 捕获异常的代码如下,此代码的部分参考自ADO手册,并加以部分的修改 
    for(;;) 

    try 

    if   (isConnected) 

    pRs-> Open(_bstr_t(sql),                               
    _variant_t((IDispatch       *)pConn,true), 
    adOpenStatic, 
    adLockReadOnly, 
    adCmdText); 
    TRACE( "Connection   State   =   %d   \n ",pConn-> State); 
    if   (pRs) 
    if   (pRs-> State   ==   adStateOpen) 
    pRs-> Close(); 

    else 

    if   (pConn) 
    if   (pConn-> State   ==   adStateOpen) 
    pConn-> Close(); 
    pConn-> Open   (_bstr_t(strCnn),_bstr_t( " "),_bstr_t( " "),adModeUnknown); 
    isConnected=TRUE; 
    } } 
    catch   (_com_error   &pCome) 
    { _variant_t   vtConnect   =   (_variant_t)(pConn.GetInterfacePtr());//pRs-> GetActiveConnection(); //   GetActiveConnection   returns   connect   string   if   connection 
    //   is   not   open,   else   returns   Connection   object. 
    switch(vtConnect.vt) 

    case   VT_BSTR: 
    PrintComError(pCome); 
    break; 
    case   VT_DISPATCH: 
    PrintProviderError(vtConnect); 
    break; 
    default: 
    printf( "Errors   occured. "); 
    break; 
    } isConnected=   FALSE; 
    } Sleep(1000); 
    } /////////////////////////////////////////////////////////// 
    //                                                                                                               // 
    //             PrintProviderError   Function                                             // 
    //                                                                                                               // 
    /////////////////////////////////////////////////////////// void   PrintProviderError(_ConnectionPtr   pConnection) 

    //   Print   Provider   Errors   from   Connection   object. 
    //   pErr   is   a   record   object   in   the   Connection 's   Error   collection. 
    ErrorPtr     pErr     =   NULL; if(   (pConnection-> Errors-> Count)   >   0) 

    long   nCount   =   pConnection-> Errors-> Count; 
    //   Collection   ranges   from   0   to   nCount   -1. 
    for(long   i   =   0;   i   <   nCount;   i++) 

    pErr   =   pConnection-> Errors-> GetItem(i); 
    TRACE( "Error   number:   %x\n%s\n ",   pErr-> Number, 
    (LPCSTR)   pErr-> Description); 
    TRACE( "SQLState   :   %s\n ",   (LPCTSTR)pErr-> SQLState); 
    TRACE( "NativeError   :   %x\n ",   pErr-> NativeError); 


    } /////////////////////////////////////////////////////////// 
    //                                                                                                               // 
    //             PrintComError   Function                                                       // 
    //                                                                                                               // 
    /////////////////////////////////////////////////////////// void   PrintComError(_com_error   &e) 

    _bstr_t   bstrSource(e.Source()); 
    _bstr_t   bstrDescription(e.Description()); //   Print   Com   errors.     
    TRACE( "Error\n "); 
    TRACE( "\tCode   =   %08lx\n ",   e.Error()); 
    TRACE( "\tCode   meaning   =   %s\n ",   e.ErrorMessage()); 
    TRACE( "\tSource   =   %s\n ",   (LPCSTR)   bstrSource); 
    TRACE( "\tDescription   =   %s\n ",   (LPCSTR)   bstrDescription); 

    这是我在07年时的一个有关此问题的分析,供参考
      

  8.   

    oracle的可能有所不同,如果实在不行,要connection-> Close();connection.Release();connection=NULL;connection.CreateInstance(__uuidof(Connection)); 
    从新创建实例,并open链接
      

  9.   

    谢谢各位!1.使用 vieri_ch(楚谜-曾经的尘雨)  的服务端游标的链接对象来检测的方法,
      当使用pconn->CursorLocation  =  adUseServer; 
         也不能在网线拔掉的时候Open失败。
      使用pconn->CursorLocation  =  adUseClient;
        同理。
    2. 对qimiao77 (点燃的香烟) ADO有一个缓冲的过程,
      通过实验后理解了,通过测试,如果使用
      pconn->CursorLocation  =  adUseServer; 
        拔掉网线大概10多分钟,Open返回false.
      pconn->CursorLocation  =  adUseClient; 
        拔掉网线大概4分钟左右,Open返回false.
    因为Connect 缺省使用adUseServer方式,所以等待ADO真正断开要10多分钟左右。    
      

  10.   

    归根到底,使用connection是无法准确确定类似物理链路或者数据库服务终止的情况,并且在这种情况下,实现很好的failover机制。使用查询时的异常结果来判断,并且重新create新的数据库链接对象。应该是可行的。简单的用再次open是无法实现failover的
      

  11.   

    create新的数据库连接对象,也不能解决问题。
    我现在的处理方式就是:
    1.如果"select"查询失败。
    2.create一个新的connection对象。
    3.使用此新connection对象Open。我使用xp sp3的系统,难道与ado得版本有关吗