examples - Java 7 Automatic Resource Management JDBC(declaración try-with-resources)
try with resources jdbc (3)
¿Cómo integrar la expresión JDBC común de crear / recibir una conexión, consultar la base de datos y posiblemente procesar los resultados con la administración de recursos automática de Java 7, la declaración try-with-resources? ( Tutorial )
Antes de Java 7, el patrón habitual era algo como esto:
Connection con = null;
PreparedStatement prep = null;
try{
con = getConnection();
prep = prep.prepareStatement("Update ...");
...
con.commit();
}
catch (SQLException e){
con.rollback();
throw e;
}
finally{
if (prep != null)
prep.close();
if (con != null)
con.close();
}
Con Java 7 puedes ir por:
try(Connection con = getConnection(); PreparedStatement prep = con.prepareConnection("Update ..."){
...
con.commit();
}
Esto cerrará Connection
y PreparedStatement
, pero ¿qué pasa con el rollback? No puedo agregar una cláusula catch que contenga la reversión, porque la conexión solo está disponible dentro del bloque try.
¿Todavía defines la conexión fuera del bloque try? ¿Cuál es la mejor práctica aquí, especialmente si se usa la agrupación de conexiones?
La OMI, que declara Connection y PreparedStatement fuera de try-catch, es la mejor manera disponible en este caso.
Si desea utilizar la conexión agrupada en la transacción, debe usarlo de esta manera:
try (Connection conn = source.getConnection()) {
conn.setAutoCommit(false);
SQLException savedException = null;
try {
// Do things with connection in transaction here...
conn.commit();
} catch (SQLException ex) {
savedException = ex;
conn.rollback();
} finally {
conn.setAutoCommit(true);
if(savedException != null) {
throw savedException;
}
}
} catch (SQLException ex1) {
throw new DataManagerException(ex1);
}
Este código de ejemplo maneja la configuración de los valores de autocommitimiento.
try(Connection con = getConnection()) {
try (PreparedStatement prep = con.prepareConnection("Update ...")) {
//prep.doSomething();
//...
//etc
con.commit();
} catch (SQLException e) {
//any other actions necessary on failure
con.rollback();
//consider a re-throw, throwing a wrapping exception, etc
}
}
De acuerdo con la documentación de Oracle , puede combinar un bloque try-with-resources con un bloque try normal. IMO, el ejemplo anterior captura la lógica correcta, que es:
- Intente cerrar el Estado Preparado si nada sale mal
- Si algo sale mal en el bloque interno, (no importa lo que sea) revierte la transacción actual
- Intentar cerrar la conexión sin importar qué
- Si algo sale mal cerrando la conexión, no puede deshacer la transacción (ya que es un método en la conexión, que ahora está en un estado indeterminado), así que no intente
En java 6 y anteriores, haría esto con un conjunto de bloques try triply anidados (try-finally externo, try-catch medio, try-finally interno). La sintaxis de ARM hace que este terser.