Contenido del curso
Primeros pasos
Spring Data Repositories
- 7

Qué son los Spring Data Repositories
08:39 min - 8

Guardar y Actualizar Registros con Spring Data Repositories
08:34 min - 9

Eliminar elementos con Spring Data JPA: método deleteById
05:36 min - 10

Lazy vs Eager en relaciones JPA
15:09 min - 11

Query Methods en Spring para Consultas Personalizadas
08:27 min - 12

Filtrar pizzas con Containing y Not en JPA
07:27 min - 13

Fechas y listas en query methods de JPA
11:25 min - 14

findTop y Optional en Spring Data JPA
09:30 min - 15

Paginación y Ordenación con Spring Data Repositories
07:39 min - 16

Ordenamiento Dinámico con Paging and Sorting Repository
07:58 min
Personalización de queries
Características avanzadas
Próximos pasos
@Transactional y propiedades ACID en Spring
Resumen
Cuando trabajas con bases de datos en Spring, necesitas garantizar que cada operación se complete sin dejar datos a medias. La anotación @Transactional en Spring Data te permite cumplir con las propiedades ACID y proteger la integridad de tu información en escenarios reales como actualizar precios, guardar entidades o enviar notificaciones.
Qué son las propiedades ACID en una transacción
Una transacción confiable debe cumplir cuatro características que aseguran que los datos lleguen completos y consistentes a la base de datos.
- Atomicidad: todo o nada. Si ocurre un error a mitad del proceso, se ejecuta un rollback para regresar la información a su estado inicial. Si todo sale bien, los cambios quedan persistentes.
- Consistencia: solo se permiten operaciones que respeten la integridad de los datos. Por ejemplo, no puedes usar foreign keys que apunten a registros inexistentes.
- Aislamiento: cada transacción se ejecuta independiente de otras que estén ocurriendo en paralelo, evitando que la información se mezcle.
- Durabilidad: los cambios persisten en el tiempo. Si descargas una base de datos y la restauras, las transacciones previas siguen ahí.
¿Qué significa ACID en bases de datos? Es el acrónimo de Atomicidad, Consistencia, Aislamiento y Durabilidad. Son las cuatro propiedades que toda transacción debe cumplir para considerarse confiable.
Cómo funciona la anotación @Transactional en Spring Data
Con solo anotar un método con @Transactional, Spring se encarga de envolver todas las operaciones de base de datos dentro de una misma transacción atómica [1:55].
La regla práctica es simple: siempre que un método tenga dos o más llamadas a la base de datos, anótalo con @Transactional. Así te aseguras de que las operaciones se ejecuten secuencialmente como una sola unidad.
Imagina que actualizas el precio de una pizza y luego ejecutas un pizzaRepository.save() para guardar otra entidad. Si el save falla, el precio ya modificado quedaría inconsistente. Con @Transactional, ese error dispara un rollback automático que devuelve todo al estado anterior.
Ejemplo práctico con una excepción personalizada
Para probar el comportamiento, se crea un paquete exception dentro del paquete service y dentro una clase que extiende de RuntimeException [3:25]:
java public class EmailAPIException extends RuntimeException { public EmailAPIException() { super("Error sending email"); } }
Luego, un método privado sendEmail() lanza esa excepción justo después de actualizar el precio:
java private void sendEmail() { throw new EmailAPIException(); }
Al ejecutar un PUT para cambiar el precio de la pizza con ID 7 de $20 a $19.90, la API responde con un error 500 Internal Server Error. Al consultar de nuevo el precio, sigue siendo $20: el rollback funcionó porque ambas operaciones viven dentro de la misma transacción [4:50].
Cuándo usar noRollbackFor y rollbackFor
No siempre quieres que todo se revierta. Si enviar un email falla, ¿debería eso impedir que el precio se actualice? Probablemente no, porque son procesos independientes.
Para estos casos, @Transactional ofrece dos parámetros clave:
- rollbackFor: fuerza el rollback cuando ocurre una excepción específica.
- noRollbackFor: evita el rollback cuando ocurre una excepción específica y permite hacer commit de los cambios previos.
java @Transactional(noRollbackFor = EmailAPIException.class) public void updatePrice(...) { // actualizar precio sendEmail(); }
Al repetir la prueba con esta configuración, sigues recibiendo el error 500 por el email fallido, pero el precio de la pizza sí cambia en la base de datos [6:15]. Justo el comportamiento que necesitas cuando una operación secundaria no debe bloquear la principal.
¿Cuál es la diferencia entre rollbackFor y noRollbackFor?
rollbackForindica qué excepciones deben revertir la transacción;noRollbackForindica cuáles deben permitir el commit aunque se lancen.
Qué es la propagación en @Transactional y para qué sirve
La propiedad propagation define cómo se comporta un método transaccional cuando ya existe (o no) una transacción activa.
El valor por defecto es Required: si hay una transacción en curso, el método se une a ella; si no la hay, Spring crea una nueva automáticamente.
Otro valor común es Mandatory: exige que ya exista una transacción para ejecutar el método. Si no hay ninguna, lanza una excepción en lugar de crearla.
¿Qué hace propagation = Required en Spring? Es el comportamiento por defecto: usa la transacción existente si la hay, o crea una nueva si no existe ninguna.
Existen más tipos de propagación (Supports, Never, Nested, entre otros) y vale la pena revisar la documentación oficial para entender cada caso de uso.
Buenas prácticas al trabajar con transacciones en Spring
Usar @Transactional no es opcional cuando manejas operaciones críticas. Algunas recomendaciones que se desprenden de la clase:
- Anota con
@Transactionalcualquier método que ejecute dos o más llamadas a la base de datos. - Usa
noRollbackForpara excepciones de servicios externos (como envío de emails) que no deberían afectar la persistencia principal. - Define
rollbackForcuando trabajes con excepciones checked que por defecto Spring no revierte. - Revisa el tipo de propagación según el flujo de tu aplicación:
Requiredpara la mayoría de los casos,Mandatorycuando exiges contexto transaccional previo.
Con esto, tu proyecto Spring Data JPA queda más robusto y preparado para escalar. ¿Has tenido algún caso donde un rollback inesperado te haya causado problemas en producción? Cuéntame en los comentarios cómo lo resolviste.