Consideremos el siguiente código
try{ // bloque transaccional
connection.setAutoCommit(false); // tus transacciones aqui ..... connection.commit();}catch (Exception e){// En caso de Exception try { connection.rollback();} catch (SQLException ee) { ServerLogger.info("WARNING: Imposible connection.rollback()."); }}finally{// En cualquier caso de restauro autocommit true try { connection.setAutoCommit(true);} catch (SQLException ee) { ServerLogger.info("WARNING: Imposible connection.setAutoCommit(true)."); }}El problema con el bloque anterior es que solo está preparado para capturar un throw Exception y en caso de ocurrir un throw Error en alguna parte de la transacción este no será capturado, por ende nunca se ejecutará la sentencia connection.rollback(); contenida en el bloque catch (Exception e).
La razón está dada por la herencia de las excepciones. Un bloque catch (Exception e) solo puede capturar aquellas excepciones distintas a ella que estén bajo su árbol de herencia, por ello nunca capturará un Error.
Para evitar este problema se recomienda el uso de Throwable en vez de Exception en el bloque catch, no perdiendo la consideración que en caso de que se capture un error, el servicio, ajax etc, debiera terminar inmediatamente su ejecución y registrar dicho error.
Por ende la forma correcta de realizar un bloque transaccional y así evitar dejar data corrupta al no realizar un roolback es la siguiente:
try{ // bloque transaccional
connection.setAutoCommit(false); // tus transacciones aqui
.....
connection.commit();
}catch (Throwable e){ // En caso de Exception o Error
try { connection.rollback();}
catch (SQLException ee) {
ServerLogger.info("WARNING: Imposible connection.rollback().");
}
}finally{// En cualquier caso de restauro autocommit true
try { connection.setAutoCommit(true);}
catch (SQLException ee) {
ServerLogger.info("WARNING: Imposible connection.setAutoCommit(true).");
}
}
No hay comentarios:
Publicar un comentario