我刚刚接触OCI的使用,可能问题比较菜,请大家原谅:)Client:
  OS: WinNT 4.0 Server
  DB: Oracle client 8.1.7
Server:
  DB: Oracle x 64 bit我用的是多线程,在每一个线程中,都建立了Environment,Error,Server,Service Context, Session.在使用完后,现调用OCISessionEnd,然后OCIServerDetach()关闭连接。但是发现Server可以断开,但是Session在线程推出后依然保持连接。这样的话当运行一段时间后就会建立非常多的连接,导致Client,甚至Server无法使用。

解决方案 »

  1.   

    连接的代码段如下:
    hpEnv = NULL;
    sword RCode;   RCode = OCIEnvCreate( &hpEnv, 
    // OCI_SHARED|OCI_THREADED|OCI_OBJECT, 
    OCI_THREADED|OCI_OBJECT, 
    (dvoid*)0, 
    0, 
    0, 
    0, 
    (size_t)0, 
    (dvoid**)0); //环境创建
    if ( RCode != OCI_SUCCESS )
    {
    #ifdef _DEBUG
    AfxMessageBox("Environ Create FAIL!");
    #endif
    return FALSE;
    }
    RCode = OCIHandleAlloc( (dvoid*)hpEnv, 
    (dvoid**)&hpError, 
    (ub4)OCI_HTYPE_ERROR, 
    (size_t)0, 
    (dvoid**)0 ); // 错误处理 句柄分配
    if ( RCode != OCI_SUCCESS )
    {
    #ifdef _DEBUG
    AfxMessageBox("Error Alloc FAIL!");
    #endif
    return FALSE;
    }
    RCode = OCIHandleAlloc( (dvoid*)hpEnv, 
    (dvoid**)&hpSvcCtx, 
    (ub4)OCI_HTYPE_SVCCTX, 
    (size_t)0, 
    (dvoid**)0); // 服务上下文 句柄分配
    if ( RCode != OCI_SUCCESS )
    {
    #ifdef _DEBUG
    AfxMessageBox("SvcCtx Alloc FAIL!");
    #endif
    return FALSE;
    }
    RCode = OCIHandleAlloc( (dvoid*)hpEnv, 
    (dvoid**)&hpServer, 
    (ub4)OCI_HTYPE_SERVER, 
    (size_t)0, 
    (dvoid**)0 );  // 服务句柄分配
    if ( RCode != OCI_SUCCESS )         
    {
    #ifdef _DEBUG
    AfxMessageBox("hpServer Alloc FAIL!");
    #endif
    return FALSE;
    }

       // 建立与服务器的连接
    RCode = OCIServerAttach( hpServer, 
     hpError, 
     (text*)(LPCTSTR)dbalias, 
     (sb4)dbalias.GetLength(), 
     OCI_DEFAULT
     );
    if( RCode != OCI_SUCCESS )
    {
    #ifdef _DEBUG
    AfxMessageBox("Database Set FAIL!");
    error_proc(hpError, errorcode, errormessage, 512, RCode);
    #endif

    return FALSE;
    }
       // 服务上下文的 OCI_ATTR_SERVER 属性设置
    RCode = OCIAttrSet( (dvoid*)hpSvcCtx, 
    (ub4)OCI_HTYPE_SVCCTX, 
    (dvoid*)hpServer, 
    (ub4)0, 
    (sb4)OCI_ATTR_SERVER, 
    hpError
    );
    if( RCode != OCI_SUCCESS )
    {
    #ifdef _DEBUG
    AfxMessageBox("hpSrver Set FAIL!");
    #endif
    return FALSE;
    }
       // 会话句柄分配
       RCode = OCIHandleAlloc( (dvoid*)hpEnv, 
    (dvoid**)&hpSession, 
    (ub4)OCI_HTYPE_SESSION, 
    (size_t)0, 
    (dvoid**)0
      );
    if ( RCode != OCI_SUCCESS )
    {
    #ifdef _DEBUG
    AfxMessageBox("hpSession Alloc FAIL!");
    #endif
    return FALSE;
    }
       // 设置会话用户名属性
    RCode = OCIAttrSet( (dvoid*)hpSession, 
    (ub4)OCI_HTYPE_SESSION, 
    (dvoid*)(LPCTSTR)user, 
    (ub4)user.GetLength(), 
    (sb4)OCI_ATTR_USERNAME, 
    hpError
    );
    if( RCode != OCI_SUCCESS )
    {
    #ifdef _DEBUG
    AfxMessageBox("User Set FAIL!");
    #endif
    return FALSE;
    }
       // 设置会话口令属性
    RCode = OCIAttrSet( (dvoid*)hpSession, 
    (ub4)OCI_HTYPE_SESSION, 
    (dvoid*)(LPCTSTR)pwd, 
    (ub4)pwd.GetLength(), 
    (sb4)OCI_ATTR_PASSWORD, 
    hpError
    );
    if( RCode != OCI_SUCCESS )
    {
    #ifdef _DEBUG
    AfxMessageBox("PASSWORD Set FAIL!");
    #endif

    return FALSE;
    }
       // 建立会话
    RCode = OCISessionBegin( hpSvcCtx, 
                   hpError, 
     hpSession, 
     (ub4)OCI_CRED_RDBMS, 
     (ub4)OCI_DEFAULT
     );
    if( RCode != OCI_SUCCESS )
    {
    OCIServerDetach( hpServer, 
    hpError, 
    OCI_DEFAULT
    );
    #ifdef _DEBUG
    AfxMessageBox("Session begin FAIL!");
    #endif

    return FALSE;
    }
       // 将会话与服务上下文关联
    RCode = OCIAttrSet( (dvoid*)hpSvcCtx, 
    (ub4)OCI_HTYPE_SVCCTX, 
    (dvoid*)hpSession, 
    (ub4)0, 
    (sb4)OCI_ATTR_SESSION, 
    hpError
    );
    if( RCode != OCI_SUCCESS )
    {
    #ifdef _DEBUG
    AfxMessageBox("hpSession Set FAIL!");
    #endif

    return FALSE;
    }
    m_bConnected = TRUE;
    return TRUE;
      

  2.   

    断开的代码段如下:
    m_bConnected = FALSE;

    sword RCode;
    if ( hpEnv == NULL )
    {
    return FALSE;
    }
    // 关闭会话
    if ( hpSession )
    RCode = OCISessionEnd( hpSvcCtx, 
    hpError, 
    hpSession, 
    OCI_DEFAULT
    );
    if( RCode != OCI_SUCCESS )
    {
    return FALSE;
    }

    RCode = OCIHandleFree( (dvoid*)hpSession, (ub4)OCI_HTYPE_SESSION );
    if ( RCode != OCI_SUCCESS )
    {
    return FALSE;
    } // 断开与服务器的连接
    if ( hpServer )
    RCode = OCIServerDetach( hpServer, 
     hpError, 
     OCI_DEFAULT
     );
    if( RCode != OCI_SUCCESS )
    {
    return FALSE;
    }
    RCode = OCIHandleFree( (dvoid*)hpSvcCtx, (ub4)OCI_HTYPE_SVCCTX );
    if ( RCode != OCI_SUCCESS )
    {
    return FALSE;
    }

    RCode = OCIHandleFree( (dvoid*)hpServer, (ub4)OCI_HTYPE_SERVER );
    if ( RCode != OCI_SUCCESS )
    {
    return FALSE;
    }

    RCode = OCIHandleFree( (dvoid*)hpError, (ub4)OCI_HTYPE_ERROR );
    if ( RCode != OCI_SUCCESS )
    {
    return FALSE;
    }

        RCode = OCIHandleFree( (dvoid*)hpEnv, (ub4)OCI_HTYPE_ENV );
    if ( RCode != OCI_SUCCESS )
    {
    return FALSE;
    } hpSvcCtx = NULL;
    hpSession = NULL;
    hpServer = NULL;
    hpEnv = NULL;
    hpError = NULL; return 1;
      

  3.   

    同样的代码在WinXP home + Oracle 9i Client就没有上述问题。还请高手赐教
      

  4.   

    问题大概已经找到,应该是操作系统和oracle配合的问题,在nt4+oracle 815,816,817都有上述的问题,9没有试,估计也有.win98/win2k/winxp+oracle 816也有这个问题,但是用817就没有这个问题.决定换系统了.谢谢hushuangyang的关注.