Transazione JPA manuale vs @Transactional dichiarativa
Sostituisci i verbosi blocchi begin/commit/rollback con una singola annotazione @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);
}
}
Nessun boilerplate
Un'annotazione sostituisce i ripetitivi blocchi try-catch begin/commit/rollback.
Rollback più sicuro
Il container garantisce il rollback sulle eccezioni non controllate — nessun rischio di dimenticare il blocco catch.
Controllo dichiarativo
Propagazione, isolamento e regole di rollback sono espressi come attributi dell'annotazione.
Ampiamente disponibile da Jakarta EE 8 / Java 11
La gestione manuale delle transazioni richiede chiamate esplicite a begin(), commit() e rollback() avvolte in blocchi try-catch — ogni metodo di servizio ripete questo boilerplate. L'annotazione @Transactional delega la gestione del ciclo di vita al container: inizia una transazione prima del metodo, esegue il commit in caso di successo e il rollback in caso di RuntimeException automaticamente.