✅ 트랜잭션 어노테이션 기본 구분

구분 jakarta.transaction.Transactional org.springframework.transaction.annotation.Transactional
패키지 jakarta.transaction.* (또는 javax.transaction.*) org.springframework.transaction.annotation.*
표준 여부 Jakarta EE / JTA 표준 Spring 전용 어노테이션
지원 환경 JTA 환경 (Java EE, Jakarta EE, 일부 Spring 지원) Spring Framework 기반 환경 전용
트랜잭션 매니저 JTA 트랜잭션 매니저 (ex: Atomikos, Narayana, Bitronix) Spring PlatformTransactionManager 구현체
프록시 기반 처리 컨테이너에 따라 다름 (Spring은 제한적) AOP 기반 프록시를 통한 제어

✅ 주요 기능 비교

항목 jakarta.transaction.Transactional Spring Transactional
전파 설정 TxType.REQUIRED, REQUIRES_NEW, MANDATORY, SUPPORTS, NOT_SUPPORTED, NEVER Propagation.REQUIRED, REQUIRES_NEW, NESTED, 등
격리 수준 설정 ❌ 불가 (JTA 표준은 미지원) isolation = Isolation.READ_COMMITTED, 등
rollbackFor 등 상세 옵션 ❌ 기본 예외 처리만 (RuntimeException 계열) rollbackFor, noRollbackFor, timeout, readOnly 등 풍부
내부 호출 분리 보장 컨테이너/프레임워크에 따라 다름 같은 클래스의 메서드 호출 시 트랜잭션 분리 안 됨
스프링 이벤트, AOP 등과 연동 제한적 매우 뛰어남 (스프링 전용이므로)

✅ 권장 방식

조건 권장 방식
Spring Boot / Spring Data JPA 사용 중 @org.springframework.transaction.annotation.Transactional 사용 추천
Atomikos 등 JTA 매니저 사용 @jakarta.transaction.Transactional 허용됨
내부 메서드에서 트랜잭션 분리를 기대 Spring 방식은 별도 Bean 분리 필요 / Jakarta 방식은 매니저에 따라 다름
여러 설정을 유연하게 제어하고 싶음 Spring 방식이 더 풍부한 옵션 제공

🤔 왜 Spring AOP 기반 트랜잭션이 JPA 에 적합할까 ?

특징 Spring AOP 기반 트랜잭션 JPA
적용 시점 메서드 진입 직전 (프록시) 엔티티 변경 감지 및 flush 시점
트랜잭션 경계 메서드 단위로 경계 설정 가능 flush 시점이 트랜잭션 안에서만 동작
롤백 처리 자동 감지 (RuntimeException 이상) 트랜잭션 rollback 없으면 dirty check 무의미
주된 라이프사이클 메서드 호출 → 트랜잭션 시작 → 커밋/롤백 트랜잭션 내 영속성 컨텍스트 유지

👉🏻트랜잭션과 프록시