Ręczna transakcja JPA kontra deklaratywna @Transactional
Zastąp rozwlekłe bloki begin/commit/rollback pojedynczą adnotacją @Transactional.
Porównanie kodu
✕ Java EE
@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;
}
}
✓ Jakarta EE 8+
@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);
}
}
Widzisz problem z tym kodem? Daj nam znać.
Dlaczego nowoczesne podejście wygrywa
Bez boilerplate
Jedna adnotacja zastępuje powtarzające się bloki try-catch begin/commit/rollback.
Bezpieczniejsze wycofanie
Kontener gwarantuje wycofanie przy wyjątkach unchecked — bez ryzyka zapomnienia bloku catch.
Deklaratywna kontrola
Propagacja, izolacja i reguły wycofania są wyrażone jako atrybuty adnotacji.
Stare podejście
Ręczna transakcja
Nowoczesne podejście
@Transactional
Od JDK
11
Poziom trudności
Średniozaawansowany
Wsparcie JDK
Ręczna transakcja JPA kontra deklaratywna @Transactional
Dostępne
Szeroko dostępne od Jakarta EE 8 / Java 11
Jak to działa
Ręczne zarządzanie transakcjami wymaga jawnych wywołań begin(), commit() i rollback() opakowanych w bloki try-catch — każda metoda serwisu powtarza ten boilerplate. Adnotacja @Transactional deleguje zarządzanie cyklem życia do kontenera — rozpoczyna transakcję przed metodą, zatwierdza przy sukcesie i automatycznie cofa przy RuntimeException.
Powiązana dokumentacja
Dowód