Rollback automático con @Transactional en Spring Boot

Clase 26 de 31Curso de Java: Backend con Spring Boot

Contenido del curso

JPA con Spring y Spring Data

Resumen

Cuando trabajas con bases de datos en Spring Boot, garantizar la integridad de los datos es fundamental. La anotación @Transactional permite que, ante cualquier error durante una serie de inserciones, el sistema revierta automáticamente todos los registros previos, evitando datos inconsistentes. A continuación se explica cómo funciona este mecanismo con un ejemplo práctico.

¿Cómo se provoca un error de unicidad en la base de datos?

Para demostrar el poder de @Transactional, se genera intencionalmente un error de tipo violación de índice de unicidad. Esto se logra asignando el mismo email a dos usuarios distintos dentro del código [01:00].

En la entidad User, se agrega el atributo unique dentro de la anotación @Column y se inicializa con el valor true. Esto indica que cada registro en la base de datos debe tener un email único:

java @Column(unique = true) private String email;

Al ejecutar la aplicación, el sistema lanza un error que dice "violación de índice de unicidad o clave primaria", porque dos usuarios comparten el mismo correo electrónico [01:38].

¿Qué sucede cuando se usa @Transactional ante un error?

El comportamiento clave de @Transactional es el rollback automático. Cuando el servicio anotado con esta anotación detecta una excepción durante la ejecución, revierte todas las operaciones de base de datos realizadas dentro de ese método.

Para observar este comportamiento sin que la aplicación se detenga, se envuelven las sentencias de registro dentro de un bloque try-catch [02:22]:

java try { // registros de usuarios } catch (Exception e) { log.error("Esta es una excepción dentro del método @Transactional", e); }

Al ejecutar la aplicación con @Transactional activa:

  • El sistema intenta registrar el usuario 1.
  • Intenta registrar el usuario 2.
  • Al intentar registrar el usuario 3, detecta el email duplicado.
  • Se ejecuta un rollback y ninguno de los usuarios transaccionales queda registrado [03:07].

La lista final de usuarios solo muestra los que se registraron durante la inicialización del programa (John, Daniela y los demás hasta el usuario 12), pero ningún usuario de tipo test_transaccional aparece.

¿Qué pasa si se elimina la anotación @Transactional?

Al comentar la anotación @Transactional y reiniciar la aplicación, el comportamiento cambia por completo [03:52]:

  • El usuario test1_transaccional se registra correctamente.
  • El usuario test2_transaccional también se registra.
  • El usuario test3_transaccional genera un error por el email duplicado y no se registra.
  • El usuario test4_transaccional tampoco se registra porque el flujo se interrumpe tras la excepción.

Esto significa que sin @Transactional, los registros exitosos previos al error permanecen en la base de datos, generando inconsistencia.

¿Por qué es importante usar @Transactional en desarrollo?

El concepto de rollback es esencial para mantener la coherencia de los datos. Sin esta anotación, una operación parcialmente completada puede dejar registros huérfanos o incompletos.

Al volver a habilitar @Transactional y reiniciar la aplicación, se confirma que los usuarios test1 y test2 ya no se registran porque la base de datos ejecutó el rollback completo [04:44].

Los beneficios principales son:

  • Atomicidad: todas las operaciones dentro del método se tratan como una sola unidad.
  • Consistencia: si una operación falla, ninguna de las anteriores persiste.
  • Protección automática: no es necesario escribir lógica manual de reversión.

Esta anotación resulta indispensable cuando se trabaja con múltiples inserciones o actualizaciones que deben completarse en conjunto. Si alguna parte del proceso falla, @Transactional garantiza que la base de datos vuelva a su estado anterior, protegiendo la integridad de toda la información. ¿Has tenido algún caso donde el rollback automático te haya salvado de un problema mayor? Comparte tu experiencia.