Enterprise 중급

수동 JPA 트랜잭션 대 선언적 @Transactional

장황한 begin/commit/rollback 블록을 단일 @Transactional 어노테이션으로 대체합니다.

✕ 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);
    }
}
이 코드에 문제가 있나요? 알려주세요.
🗑️

보일러플레이트 없음

하나의 어노테이션이 반복적인 begin/commit/rollback try-catch 블록을 대체합니다.

🛡️

더 안전한 롤백

컨테이너는 확인되지 않은 예외에서 롤백을 보장합니다 — catch 블록을 잊을 위험이 없습니다.

📐

선언적 제어

전파, 격리, 롤백 규칙이 어노테이션 속성으로 표현됩니다.

이전 방식
수동 트랜잭션
모던 방식
@Transactional
JDK 버전
11
난이도
중급
수동 JPA 트랜잭션 대 선언적 @Transactional
사용 가능

Jakarta EE 8 / Java 11 이후 널리 사용 가능

수동 트랜잭션 관리는 명시적 begin(), commit(), rollback() 호출과 오류 처리가 필요합니다. @Transactional은 컨테이너가 경계를 관리하도록 하여 비즈니스 코드가 일관성에 집중할 수 있게 합니다.

공유 𝕏 🦋 in