vista patrón mvc modelo ejemplo controlador aplicando java jdbc

patrón - mvc java se



¿Deben cerrarse los conjuntos de resultados y declaraciones de JDBC por separado, aunque la conexión se cierre después? (8)

Ahora estoy usando Oracle con Java. Aquí mi punto de vista:

Debe cerrar ResultSet y Statement explícitamente, ya que Oracle tiene problemas para mantener los cursores abiertos incluso después de cerrar la conexión. Si no cierra el ResultSet (cursor), se generará un error como Máximo de cursores abiertos excedidos .

Creo que puede encontrar el mismo problema con otras bases de datos que utiliza.

Aquí está el tutorial Cerrar ResultSet cuando haya terminado :

Cerrar ResultSet cuando haya terminado

Cierre el objeto ResultSet tan pronto como termine de trabajar con el objeto ResultSet a pesar de que el objeto Statement cierra el objeto ResultSet implícitamente cuando se cierra, al cerrar ResultSet se da explícitamente la posibilidad de que el recolector de basura recoja la memoria lo antes posible, ya que el objeto ResultSet puede ocupar mucha memoria dependiendo de consulta.

ResultSet.close();

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.


Con el formulario Java 6, creo que es mejor verificar si está cerrado o no antes de cerrar (por ejemplo, si un agrupador de conexiones desaloja la conexión en otro hilo), por ejemplo, algún problema de red, el estado de la declaración y el conjunto de resultados puede cerrarse. (no sucede a menudo, pero tuve este problema con Oracle y DBCP). Mi patrón es para eso (en la sintaxis Java más antigua) es:

try { ... return resp; } finally { if (rs != null && !rs.isClosed()) { try { rs.close(); } catch (Exception e2) { log.warn("Cannot close resultset: " + e2.getMessage()); } } if (stmt != null && !stmt.isClosed()) { try { stmt.close(); } catch (Exception e2) { log.warn("Cannot close statement " + e2.getMessage()); } } if (con != null && !conn.isClosed()) { try { con.close(); } catch (Exception e2) { log.warn("Cannot close connection: " + e2.getMessage()); } }

En teoría, no es 100% perfecto porque entre el control del estado de cierre y el cierre en sí hay un pequeño espacio 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 de largo plazo. Estamos utilizando este patrón en producción con una carga "promedio" (150 usuarios simultáneos) y no tuvimos ningún problema con él, por lo que nunca vemos ese mensaje de advertencia.


De los javadocs :

Cuando se cierra un objeto Statement , su objeto ResultSet actual, si existe, también se cierra.

Sin embargo, los javadocs no tienen muy claro si la Statement y el ResultSet están cerrados al cerrar la Connection subyacente. Simplemente establecen que cerrar una conexión:

Libera la base de datos de este objeto de Connection y los recursos JDBC inmediatamente, en lugar de esperar a que se liberen automáticamente.

En mi opinión, siempre cierre explícitamente los conjuntos de resultados, Statements y Connections cuando haya terminado con ellos, ya que la implementación de close podría variar entre los controladores de la base de datos.

Puede ahorrarse mucho código de placa de caldera utilizando métodos como closeQuietly en DBUtils de Apache.


El método correcto y seguro para cerrar los recursos asociados con JDBC es esto (tomado de Cómo cerrar los recursos de JDBC correctamente: cada vez ):

Connection connection = dataSource.getConnection(); try { Statement statement = connection.createStatement(); try { ResultSet resultSet = statement.executeQuery("some query"); try { // Do stuff with the result set. } finally { resultSet.close(); } } finally { statement.close(); } } finally { connection.close(); }


Java 1.7 hace que nuestras vidas sean mucho más fáciles gracias a la declaración try-with-resources .

try (Connection connection = dataSource.getConnection(); Statement statement = connection.createStatement()) { try (ResultSet resultSet = statement.executeQuery("some query")) { // Do stuff with the result set. } try (ResultSet resultSet = statement.executeQuery("some query")) { // Do more stuff with the second result set. } }

Esta sintaxis es bastante breve y elegante. Y la connection se cerrará incluso cuando no se pueda crear la statement .


Lo que has hecho es perfecto y muy buena práctica.

La razón por la que digo que 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 a connection.close() , la conexión se devolverá a la agrupación y al ResultSet / Statement ¡Nunca se cerrará y entonces se encontrará con muchos problemas nuevos!

Por lo tanto, no siempre se puede contar con connection.close() para limpiar.

Espero que esto ayude :)


No, no está obligado a cerrar nada, PERO la conexión. Según las especificaciones de JDBC, el cierre de cualquier objeto superior cerrará automáticamente los objetos inferiores. Al cerrar la Connection se cerrará cualquier Statement que haya creado la conexión. Al cerrar cualquier Statement se cerrarán todos los ResultSet creados por esa Statement . No importa si la Connection es poolable o no. Incluso la conexión polar tiene que limpiar antes de volver a la piscina.

Por supuesto, es posible que haya bucles anidados durante mucho tiempo en la Connection genera muchos enunciados, luego es apropiado cerrarlos. Sin embargo, casi nunca cierro el ResultSet , parece excesivo cuando el cierre de Statement o Connection cerrará.


Si quieres un código más compacto, sugiero usar Apache Commons DbUtils . En este caso:

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 { DbUtils.closeQuietly(rs); DbUtils.closeQuietly(stmt); DbUtils.closeQuietly(conn); }