Transação JPA Manual vs @Transactional Declarativo
Substitua blocos verbosos de begin/commit/rollback por uma única anotação @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);
}
}
Sem boilerplate
Uma anotação substitui blocos repetitivos de try-catch com begin/commit/rollback.
Rollback mais seguro
O container garante rollback em exceções não verificadas — sem risco de esquecer o bloco catch.
Controle declarativo
Propagação, isolamento e regras de rollback são expressos como atributos da anotação.
Amplamente disponível desde o Jakarta EE 8 / Java 11
O gerenciamento manual de transações exige chamadas explícitas a begin(), commit() e rollback() envolvidas em blocos try-catch — cada método de serviço repete esse boilerplate. A anotação @Transactional delega o gerenciamento do ciclo de vida ao container, que inicia uma transação antes do método, faz commit em caso de sucesso e rollback automático em caso de RuntimeException.