viernes, 28 de diciembre de 2012

Porque @Transactional no hace rollback?

Uno de los grandes inventos para usar Spring y conexiones a las base de datos es poder definir el datasource y controlar las transacciones a través de anotaciones y dejar de preocuparte de obtener la conexión, de abrir y cerrar recursos, etc.
@Service
@Transactional
public class GenericServiceImpl implements GenericService {
   public void method1(){
      try{
         ...
      }catch(Exception except){
         throws new ServiceException(except);
      }
   }
}
Algo tan sencillo como lo que tenemos arriba debería servir para hacer commit cuando termine todo correctamente y rollback cuando no. En principio uno espera que si se da una excepción en el código, pues Spring se encargue de hacer el rollback.
Pero no amigos, Spring solo hará rollback cuando sea una excepción no declarada de tipo RunTimeException. Por lo que con el código anterior, podemos hacer log de la excepción y luego lanzar nuestro tipo y aún así, si hay varios métodos puede hacer commit de alguno de ellos.
Para evitar este posible erro debemos hacer lo siguiente.
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
Con propagation le hacemos indicar que todas las operaciones incluidas dentro de un mismo método deben ser tratadas con la misma transaccion. Pero lo que realmente ayuda es el rollbackFor, con esta propiedad le indicamos que debe hacer rollback si ocurre alguna excepción.

No hay comentarios:

Publicar un comentario