开启连接池
前提条件:数据源已配置成功。Linux系统请参考Linux下配置数据源;Windows系统请参考Windows下配置数据源。
在Linux和Windows环境下开启连接池,对于需要频繁建立和断开连接的中间层应用程序可显著提升性能,参考配置请参见连接池场景,示例代码如下:
#ifdef WIN32 #include <windows.h> #endif #include <stdio.h> #include <stdlib.h> #include <sql.h> #include <sqlext.h> #include <string.h> #include <sys/time.h> #include <pthread.h> #include <sqltypes.h> #include <time.h> SQLHENV env; SQLHDBC conn; struct timeval start, end; #define CONN_COUNT 15000 #define CHECK_ERROR(retcode, str, handle, htype) \ ({ \ if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) { \ fprintf(stderr, "FAILED:\t"); \ extract_error(str, handle, htype); \ exit(-1); \ } else { \ printf("OK:\t%s\n", str); \ } \ }) void print_diag(char *msg, SQLSMALLINT htype, SQLHANDLE handle) { char sqlstate[32]; char message[1000]; SQLINTEGER nativeerror; SQLSMALLINT textlen; SQLRETURN ret; if (msg) { printf("%s\n", msg); } ret = SQLGetDiagRec(htype, handle, 1, sqlstate, &nativeerror, message, 256, &textlen); if (ret != SQL_ERROR) { printf("%s=%s\n", (CHAR *)sqlstate, (CHAR *)message); } } void extract_error(char *fn, SQLHANDLE handle, SQLSMALLINT type) { SQLINTEGER i = 0; SQLINTEGER NativeError; SQLCHAR SQLState[7]; SQLCHAR MessageText[256]; SQLSMALLINT TextLength; SQLRETURN ret; fprintf(stderr, "The driver reported the following error %s\n", fn); if (NULL == handle) return; do { ret = SQLGetDiagRec(type, handle, ++i, SQLState, &NativeError, MessageText, sizeof(MessageText), &TextLength); if (SQL_SUCCEEDED(ret)) { printf("[SQLState:%s]:[%ldth error]:[NativeError:%ld]: %s\n", SQLState, (long)i, (long)NativeError, MessageText); } } while (ret == SQL_SUCCESS); } void InitializeEnvironment() { /* Windows配置连接池参数,需要在分配环境句柄前完成,此处为开启连接池 */ SQLSetEnvAttr(env, SQL_ATTR_CONNECTION_POOLING, (SQLINTEGER *)SQL_CP_ONE_PER_DRIVER, 0); /* 在Win上关闭连接池 */ // SQLSetEnvAttr(env, SQL_ATTR_CONNECTION_POOLING, (SQLINTEGER*)SQL_CP_OFF, 0); // 分配环境句柄 SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env); // 配置ODBC版本 SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0); // 配置建连超时时间 SQLSetConnectAttr(conn, SQL_LOGIN_TIMEOUT, (SQLPOINTER *)5, 0); } void test_connect() { SQLRETURN ret; SQLCHAR str[1024]; SQLSMALLINT strl; SQLCHAR dsn[1024]; SQLUINTEGER uIntVal; SQLAllocHandle(SQL_HANDLE_DBC, env, &conn); /* 根据场景需要调整连接串 */ char *config = "Driver=GaussMPP;DSN=gaussdb;"; ret = SQLSetConnectAttr(conn, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)(1), 0); ret = SQLDriverConnect(conn, 0, (SQLCHAR *)config, SQL_NTS, (SQLCHAR *)NULL, SQL_NTS, 0, SQL_DRIVER_NOPROMPT); if (SQL_SUCCEEDED(ret)) { // printf("Connected\n"); } else { print_diag("SQLDriverConnect failed.", SQL_HANDLE_DBC, conn); SQLFreeHandle(SQL_HANDLE_DBC, conn); SQLFreeHandle(SQL_HANDLE_ENV, env); exit(1); } /* 将连接放入连接池以重用连接 */ if (conn != SQL_NULL_HDBC) { SQLDisconnect(conn); SQLFreeHandle(SQL_HANDLE_DBC, conn); conn = SQL_NULL_HDBC; } } int main() { int count = 0; int timeuser; gettimeofday(&start, NULL); InitializeEnvironment(); for (int i = 0; i < CONN_COUNT; i++) { test_connect(); count++; } //释放环境句柄 SQLFreeHandle(SQL_HANDLE_ENV, env); printf("Connection count: %d\n", count); gettimeofday(&end, NULL); timeuser = 1000000 * (end.tv_sec - start.tv_sec) + end.tv_usec - start.tv_usec; printf("Connection time: %.3f s \n", (double)timeuser / 1000000); return 0; }
不同环境下结果不一,在连接池打开的情况下,本示例运行结果如下:
Connection count: 15000 Connection time: 14.175 s
在连接池关闭的情况下,本示例运行结果如下:
Connection count: 15000 Connection time: 691.768 s
Windows环境应用代码同Linux环境如上,连接串需根据场景进行配置。