2009-10-26 12 views
7

Hemos encontrado un error en el código anterior donde las conexiones no se cierran. Es una solución fácil, pero me pregunto cómo hacemos para probar que está solucionado. Existe la opción de usar un grupo de conexión o no. Para el uso de la agrupación, sería fácil agregar monitoreo para el grupo, pero cuando no se utiliza la agrupación de conexiones, ¿cómo rastreamos esas conexiones huérfanas no cerradas? ¿Es como cualquier otra pérdida de memoria?¿Cómo realizo un seguimiento de conexiones JDBC huérfanas que no están cerradas?

El error parece básicamente un error de cortar y pegar. Tenemos algunas clases que gestionan la conexión DB, por lo que se ve más o menos así:

OurDBConn conn1 = ConnectionManager.getConnection(); 
try { 
    // business logic 
} catch() { 
    // 
} finally { 
    ConnectionManager.returnConnection(conn1); 
} 

/// and then later in the same method 
OurDBConn conn2 = ConnectionManager.getConnection(); 
try { 
    // business logic 
} catch() { 
    // 
} finally { 
    ConnectionManager.returnConnection(conn1); // NOTE Error: conn1 should be conn2 
} 

No sé por qué los codificadores anteriores no acaba de volver a utilizar la conexión original, pero eso es lo que es

(comenzar a editar/anexar)

Sí, el código de conexión es nuestro también y puedo usar las respuestas dadas.

Sin embargo, no creo que haya hecho la pregunta correcta, aunque las respuestas a continuación responden la pregunta que hice. No estoy seguro de qué es lo correcto de stackoverflow para hacer; haga otra pregunta, o edite esta?

Una de las preguntas que debería haber hecho es: ¿cómo se manifestarían estas conexiones huérfanas y no cerradas en el rendimiento del sistema? Además, dado que estos objetos de conexión existen solo dentro del alcance de un método determinado, ¿las conexiones no serían elegibles para la recolección de basura? Y luego, si se les aplica gc, ¿cuál es el efecto de las conexiones abiertas que se generan?

(final de edición)

+0

Estaré mirando de cerca, tenemos un problema muy similar en varios de nuestros proyectos. – Tenner

+1

Para que conste, necesitaría una muy buena razón para NO mover esto a una implementación de grupo de conexión madura como DBCP o C3PO, si tiene la oportunidad, ¿quizás debería considerar hacerlo? – teabot

Respuesta

7

Suponiendo que el administrador de conexión es también su propio código, que podría almacenar las conexiones inicializado (junto con un StackTrace) en un mapa dentro del administrador de conexión, y luego eliminarlos cuando se vuelven . Por lo tanto, en cualquier punto, el conjunto de claves del mapa es el conjunto de conexiones no devueltas, y puede buscar ese valor en el mapa para encontrar el código culpable del código que las creó y nunca las lanzó. (Si la conexión no es una clave de mapa adecuada, probablemente pueda usar algún tipo de ID único o número de conexión, o lo que sea, el valor real no importa tanto como su presencia).

A continuación, solo agregue una forma apropiada de acceder a este mapa bajo demanda y estará bien. Dependiendo de su entorno, agregar un gancho de apagado que vuelque el contenido del mapa en un archivo y/o agregar una interfaz JConsole para buscar el conjunto de conexiones no cerradas en el código en ejecución, ambas podrían ser buenas opciones.

Si el administrador de conexión no es su código, aún podría lograr lo mismo utilizando aspectos.

+0

+1 para el enfoque de AOP – teabot

+0

El grupo de conexiones que utilizamos hace algo como esto; Creo que envuelve las conexiones que devuelve y realiza un seguimiento de cuándo se usan. Si no se utiliza una conexión durante un tiempo superior al especificado en la configuración, la conexión finalizará automáticamente y el seguimiento de la pila que se registró en la conexión abierta se imprimirá en el registro. – RMorrisey

0

Puede implementar mini-framework personalizado o usar exisitng one como thin wrapper en operaciones JDBC. Por ejemplo, hay un módulo spring-jdbc (mavenized) que cubre todos los códigos repetitivos del desarrollador.

Puede verificar su usage examples y ver que no haya ninguna inicialización/limpieza en el código del cliente. Utiliza 'método de plantilla' patrón, es decir, solo escribe el procesamiento de datos esenciales y no se molesta con la creación/cierre de conexiones/declaraciones/resultados. Por lo tanto, no es posible introducir el problema al que hablaste al principio.

Cuestiones relacionadas