注册

DM OCI方式使用连接池的不能检测断网问题和最大最小连接数设置无效问题

DM 2021/05/10 1405 8

【DM版本】:DM8
【操作系统】:centos 7
【CPU】: x86_64
【问题描述】*:

  1. 使用OCI方式的连接池,设置最大最小连接数无效(最大设置为1,但是queryRows的循环可以执行超过一次)
  2. 拔掉网线后,OCILogon2仍然返回成功,无法检测到断网,导致OCIStmtExecute函数阻塞(尝试设置OCI_ATTR_CONN_TIMEOUT提示非法属性)

源码如下:

#ifdef _WIN32 #include <windows.h> #define msleep(microsecond) Sleep(microsecond) // ms #else #include <unistd.h> #define msleep(microsecond) usleep(1000 * microsecond) // ms #endif #include <oci.h> #include <stdio.h> #include <stdlib.h> #include <string.h> OCIError *errhp; OCIEnv *envhp; OCICPool *poolhp; OraText *poolName; sb4 poolNameLen; CONST OraText *database = (OraText *)"192.168.1.1"; CONST OraText *username = (OraText *)"SYSDBA"; CONST OraText *password = (OraText *)"SYSDBA"; /* Local functions */ void checkerr(OCIError *errhp, sword status); void queryRows(); int main() { sword lstat; OCIEnvCreate(&envhp, OCI_THREADED | OCI_OBJECT, (dvoid *)0, NULL, NULL, NULL, 0, (dvoid **)0); (void)OCIHandleAlloc((dvoid *)envhp, (dvoid **)&errhp, OCI_HTYPE_ERROR, (size_t)0, (dvoid **)0); (void)OCIHandleAlloc((dvoid *)envhp, (dvoid **)&poolhp, OCI_HTYPE_CPOOL, (size_t)0, (dvoid **)0); /* CREATE THE CONNECTION POOL */ if (lstat = OCIConnectionPoolCreate(envhp,errhp, poolhp, &poolName, &poolNameLen, database, (sb4)strlen((const signed char *)database), 0, 1, 1, username, (sb4)strlen((const signed char *)username), password, (sb4)strlen((const signed char *)password), OCI_DEFAULT)) { checkerr(errhp, lstat); return; // exit(1); } // OCI_ATTR_CONN_TIMEOUT // ub4 timeout = 5; // checkerr(errhp, OCIAttrSet(poolhp, OCI_HTYPE_CPOOL, (dvoid *)&timeout, (ub4)sizeof(timeout), OCI_ATTR_CONN_TIMEOUT, errhp)); while (1) { // 最大连接数为1,正常应该只执行一次 queryRows(); msleep(1000); } checkerr(errhp, OCIConnectionPoolDestroy(poolhp, errhp, OCI_DEFAULT)); checkerr(errhp, OCIHandleFree((dvoid *)poolhp, OCI_HTYPE_CPOOL)); checkerr(errhp, OCIHandleFree((dvoid *)errhp, OCI_HTYPE_ERROR)); return 0; } void queryRows() { OCIDefine *defhp[200]; text selectst1[256]; ub4 session_count = 0; sword status = 0; sword lstat = 0; OCISvcCtx *svchp = (OCISvcCtx *)0; OCIError *errhp2 = (OCIError *)0; OCIHandleAlloc((dvoid *)envhp, (dvoid **)&errhp2, OCI_HTYPE_ERROR, (size_t)0, (dvoid **)0); /* Logon in Connection Pool mode */ if (lstat = OCILogon2(envhp, errhp2, &svchp, (CONST OraText *)username, (ub4)strlen((const signed char *)username), (CONST OraText *)password, (ub4)strlen((const signed char *)password), (CONST OraText *)poolName, (ub4)poolNameLen, OCI_CPOOL)) { printf("xx OCILogon2 lstat: %d\n", lstat); checkerr(errhp2, lstat); return; // exit(1); } printf("OCILogon2 lstat: %d\n", lstat); sprintf(selectst1, "select count(*) from v$sessions;"); OCIStmt *stmthp = (OCIStmt *)0; OCIHandleAlloc(envhp, (dvoid **)&stmthp, OCI_HTYPE_STMT, (size_t)0, (dvoid **)0); checkerr(errhp2, OCIStmtPrepare(stmthp, errhp2, (text *)selectst1, (ub4)strlen((const signed char *)selectst1), OCI_NTV_SYNTAX, OCI_DEFAULT)); checkerr(errhp2, OCIDefineByPos(stmthp, &defhp[0], errhp2, (ub4)1, (dvoid *)&session_count, (sb4)sizeof(ub4), (ub2)SQLT_INT, (dvoid *)0, (ub2 *)0, (ub2 *)0, OCI_DEFAULT)); if (lstat = OCIStmtExecute(svchp, stmthp, errhp2, (ub4)0, (ub4)0, (OCISnapshot *)0, (OCISnapshot *)0, OCI_DEFAULT)) { checkerr(errhp2, lstat); return; // exit(1); } status = OCIStmtFetch(stmthp, errhp2, 1, OCI_FETCH_NEXT, OCI_DEFAULT); while (status != OCI_NO_DATA) { printf("session_count:%u \n", session_count); status = OCIStmtFetch(stmthp, errhp2, 1, OCI_FETCH_NEXT, OCI_DEFAULT); } checkerr(errhp2, OCIHandleFree((dvoid *)stmthp, OCI_HTYPE_STMT)); // OCILogoff之后OCILogon2一直返回0 // 不调用OCILogoff,OCILogon2断网返回-1 checkerr(errhp2, OCILogoff((dvoid *)svchp, errhp2)); } void checkerr(OCIError *errhp, sword status) { text errbuf[512]; sb4 errcode = 0; switch (status) { case OCI_SUCCESS: break; case OCI_SUCCESS_WITH_INFO: (void)printf("Error - OCI_SUCCESS_WITH_INFO\n"); break; case OCI_NEED_DATA: (void)printf("Error - OCI_NEED_DATA\n"); break; case OCI_NO_DATA: (void)printf("Error - OCI_NODATA\n"); break; case OCI_ERROR: (void)OCIErrorGet((dvoid *)errhp, (ub4)1, (text *)NULL, &errcode, errbuf, (ub4)sizeof(errbuf), OCI_HTYPE_ERROR); (void)printf("Error - %d, %.*s\n", errcode, 512, errbuf); break; case OCI_INVALID_HANDLE: (void)printf("Error - OCI_INVALID_HANDLE\n"); break; case OCI_STILL_EXECUTING: (void)printf("Error - OCI_STILL_EXECUTE\n"); break; case OCI_CONTINUE: (void)printf("Error - OCI_CONTINUE\n"); break; default: (void)printf("Error - unknown error, status: %d\n", status); break; } }
回答 0
暂无回答
扫一扫
联系客服