Se dice que es un buen hábito cerrar todos los recursos JDBC después del uso. Pero si tengo el siguiente código, ¿es necesario cerrar el conjunto de resultados y la declaración?
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
conn = // Retrieve connection
stmt = conn.prepareStatement(// Some SQL);
rs = stmt.executeQuery();
} catch(Exception e) {
// Error Handling
} finally {
try { if (rs != null) rs.close(); } catch (Exception e) {};
try { if (stmt != null) stmt.close(); } catch (Exception e) {};
try { if (conn != null) conn.close(); } catch (Exception e) {};
}
La pregunta es si el cierre de la conexión hace el trabajo o si deja algunos recursos en uso.
Respuestas:
Lo que has hecho es perfecto y muy buena práctica.
La razón por la que digo es una buena práctica ... Por ejemplo, si por alguna razón está utilizando un tipo "primitivo" de agrupación de bases de datos y llama
connection.close()
, la conexión se devolverá al grupo y elResultSet
/Statement
nunca se cerrará y luego usted se encontrará con muchos problemas nuevos y diferentes!Por lo tanto, no siempre puede contar
connection.close()
para limpiar.Espero que esto ayude :)
fuente
Java 1.7 nos hace la vida mucho más fácil gracias a la declaración de prueba con recursos .
Esta sintaxis es bastante breve y elegante. Y de
connection
hecho se cerrará incluso cuandostatement
no se pueda crear.fuente
;
)De los javadocs :
Sin embargo, los javadocs no tienen muy claro si el
Statement
yResultSet
se cierran cuando cierra el subyacenteConnection
. Simplemente afirman que cerrar una conexión:En mi opinión, siempre cierre explícitamente
ResultSets
,Statements
yConnections
cuando haya terminado con ellos, la implementación declose
podría variar entre los controladores de la base de datos.Puede ahorrarse una gran cantidad de código de placa de caldera utilizando métodos como
closeQuietly
en DBUtils de Apache.fuente
Ahora estoy usando Oracle con Java. Aquí mi punto de vista:
Debe cerrar
ResultSet
yStatement
explícitamente ya que Oracle tiene problemas anteriormente con el mantenimiento de los cursores abiertos incluso después de cerrar la conexión. Si no cierra elResultSet
(cursor), arrojará un error como Máximo de cursores abiertos excedidos .Creo que puede encontrar el mismo problema con otras bases de datos que usa.
Aquí está el tutorial Cerrar ResultSet cuando haya terminado :
fuente
Si desea un código más compacto, sugiero usar Apache Commons DbUtils . En este caso:
fuente
El método correcto y seguro para cerrar los recursos asociados con JDBC esto (tomado de Cómo cerrar los recursos JDBC correctamente - Cada vez ):
fuente
No importa si
Connection
se puede orinar o no. Incluso la conexión de la piscina debe limpiarse antes de regresar a la piscina."Limpio" generalmente significa cerrar conjuntos de resultados y deshacer cualquier transacción pendiente pero no cerrar la conexión. De lo contrario, la agrupación pierde su sentido.
fuente
No, no es necesario que cierre nada PERO la conexión. Según las especificaciones JDBC, cerrar cualquier objeto superior cerrará automáticamente los objetos inferiores. Cerrar
Connection
cerrará cualquierStatement
correo electrónico que haya creado la conexión. Cerrar cualquieraStatement
cerrará todos losResultSet
correos electrónicos creados por esoStatement
. No importa siConnection
se puede orinar o no. Incluso la conexión de la piscina debe limpiarse antes de regresar a la piscina.Por supuesto, es posible que tenga bucles anidados durante mucho tiempo en la
Connection
creación de muchas declaraciones, luego cerrarlas es apropiado. SinResultSet
embargo, casi nunca cierro , parece excesivo al cerrarlosStatement
o losConnection
cerraré.fuente
Creé el siguiente método para crear One Liner reutilizable:
Uso este código en una clase principal que se hereda de todas mis clases que envían consultas DB. Puedo usar el Oneliner en todas las consultas, incluso si no tengo un conjunto de resultados. El método se encarga de cerrar el conjunto de resultados, la declaración y la conexión en el orden correcto. Así es como se ve finalmente mi bloque.
fuente
Hasta donde recuerdo, en el JDBC actual, los conjuntos de resultados y las declaraciones implementan la interfaz AutoCloseable. Eso significa que se cierran automáticamente al ser destruidos o fuera de alcance.
fuente
close
se llama al final de una declaración de prueba con recursos. Consulte docs.oracle.com/javase/tutorial/essential/exceptions/… y docs.oracle.com/javase/8/docs/api/java/lang/AutoCloseable.html .Algunas funciones de conveniencia:
fuente
Con el formulario Java 6, creo que es mejor verificar que esté cerrado o no antes de cerrar (por ejemplo, si algún agrupador de conexiones desaloja la conexión en otro hilo), por ejemplo, algún problema de red, la declaración y el estado del conjunto de resultados pueden cerrarse. (No sucede a menudo, pero tuve este problema con Oracle y DBCP). Mi patrón es para eso (en la sintaxis Java anterior) es:
En teoría, no es 100% perfecto porque entre el control del estado de cierre y el cierre en sí hay un pequeño margen para el cambio de estado. En el peor de los casos, recibirá una advertencia en mucho tiempo. - pero es menor que la posibilidad de cambio de estado en consultas a largo plazo. Estamos usando este patrón en producción con una carga "promedio" (150 usuarios simultáneos) y no tuvimos ningún problema con él, así que nunca veamos ese mensaje de advertencia.
fuente
isClosed()
pruebas, porque cerrar cualquiera de estos que ya está cerrado es un no-op. Lo que elimina el problema de la ventana de tiempo. Lo cual también se eliminaría haciendo las variables localConnection, Statement
yResultSet
.