Transacción JPA manual vs @Transactional declarativo
Reemplaza los bloques extensos de begin/commit/rollback por una sola anotación @Transactional.
@PersistenceContext
EntityManager em;
public void transferFunds(Long from, Long to,
BigDecimal amount) {
EntityTransaction tx = em.getTransaction();
tx.begin();
try {
Account src = em.find(Account.class, from);
Account dst = em.find(Account.class, to);
src.debit(amount);
dst.credit(amount);
tx.commit();
} catch (Exception e) {
tx.rollback();
throw e;
}
}
@ApplicationScoped
public class AccountService {
@PersistenceContext
EntityManager em;
@Transactional
public void transferFunds(Long from, Long to,
BigDecimal amount) {
var src = em.find(Account.class, from);
var dst = em.find(Account.class, to);
src.debit(amount);
dst.credit(amount);
}
}
Sin código repetitivo
Una sola anotación reemplaza los repetitivos bloques try-catch de begin/commit/rollback.
Rollback más seguro
El contenedor garantiza el rollback en excepciones no verificadas — sin riesgo de olvidar el bloque catch.
Control declarativo
Las reglas de propagación, aislamiento y rollback se expresan como atributos de la anotación.
Ampliamente disponible desde Jakarta EE 8 / Java 11
La gestión manual de transacciones requiere llamadas explícitas a begin(), commit() y rollback() envueltas en bloques try-catch — cada método de servicio repite este código repetitivo. La anotación @Transactional delega la gestión del ciclo de vida al contenedor: inicia una transacción antes del método, confirma en caso de éxito y revierte en caso de RuntimeException automáticamente.