2011-09-14 39 views
7

Nuestro producto es un procesador de transacción de escucha TCP. A las conexiones entrantes se les asigna un hilo para manejar la conexión y una conexión de DB con la que trabajar.Manera eficiente de probar la conexión ODBC

En lugar de enfoque costoso de establecer nueva conexión de base de datos para cada conexión entrante de clientes, mantenemos un grupo de conexiones de bases de datos.

La agrupación de conexiones de base de datos bastante configurable: min/max tamaños, las tasas de crecimiento, etc.

Algunos detalles:

  • plataforma es Windows 2003/2008 R2
  • DB es SQL Server 2005/2008 R2
  • método de conexión ODBC es
  • lenguaje de programación C++ es

Por último, la pregunta:

A medida que el servicio podría estar en funcionamiento durante varios meses sin volver a empezar, hay una posibilidad real de que algunas de las conexiones de base de datos en la piscina de ser válida. Quiero tener la mayor rapidez posible para probar la validez de una conexión determinada antes de asignarla a una conexión entrante.

Actualmente, esto lo hago ejecutando la instrucción SQL simple "SELECT 123;", sin embargo, he encontrado que esto tiene un impacto negativo significativo en el rendimiento cuando se usan planes de ejecución en paralelo.

Muy brevemente en el código, lo que estoy haciendo es:

// ... at some point we decide pool needs another connection... 

// Set up database connection 
SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env); 
SQLAllocHandle(SQL_HANDLE_DBC, env, &conn); 
SQLDriverConnect(conn, 0, in_str, in_len, out_str, DIM(out_str), &out_len, SQL_DRIVER_NOPROMPT); 

// 'conn' is placed in DB connection pool 

// ... some time later a new client connection comes in ... 

// Execute simple statement to test if 'conn' is still OK 
SQLAllocHandle(SQL_HANDLE_STMT, conn, &stmt); 
SQLExecDirect(stmt, (SQLCHAR*)"SELECT 1;", SQL_NTS); 

// If 'conn' is OK, give it to incoming connection; 
// if not, get another connection from pool 

Cheers,
de Dave

+0

Creo que su única opción aquí es simplemente verificar las conexiones más a menudo, pero no siempre. ¿Tal vez cada 5 minutos más o menos? –

Respuesta

7

Bueno, la forma oficial es SQLGetConnectAttr (SQL_ATTR_CONNECTION_DEAD) que pone a prueba si la conexión estaba trabajando la última vez intentó.

O SQLGetConnectAttr (conn, SQL_COPT_SS_CONNECTION_DEAD, ...) que prueba si la conexión está funcionando ahora.

+0

Eso es genial - marcaré como respondí una vez que haya probado esto. – user390935

+0

Hola Nick, Una mejor manera es: SQLGetConnectAttr (conn, SQL_COPT_SS_CONNECTION_DEAD, ...) ya que esto prueba si la conexión está funcionando ahora. SQL_ATTR_CONNECTION_DEAD solo prueba si la conexión estaba funcionando la última vez que se intentó. Sin embargo, gracias por el puntero inicial, me puso en el camino correcto. Saludos, Dave. – user390935

+1

Creo que el segundo es específico de Windows, ya que en unixODBC no existe tal definición y solo puedo encontrar "SQL_ATTR_CONNECTION_DEAD". ¿Se espera que sea de esa manera (tal vez una versión más nueva de especificaciones ODBC)? – a1an

Cuestiones relacionadas