SPRING

[SPRING] @TransactionalEventListener

도원좀비 2025. 5. 13. 21:24

1️⃣ TransactionalEventListener란?

@TransactionalEventListener는 Spring의 이벤트 기반 프로그래밍에서,트랜잭션 커밋 이후에 이벤트를 처리하고자 할 때 사용
@EventListner의 기능을 확장한 것

 

주문이 저장된 후 이메일을 보내는 작업을 하고 싶다면, 단순 @EventListener는 트랜잭션이 커밋되기 전에

이벤트를 처리할 수 있어 위험,  이때 @TransactionalEventListener를 사용하면

트랜잭션이 정상적으로 커밋된 이후에 이벤트를 처리


2️⃣ 사용 예시

1. 이벤트 클래스

public class OrderCompletedEvent {
    private final Long orderId;

    public OrderCompletedEvent(Long orderId) {
        this.orderId = orderId;
    }

    public Long getOrderId() {
        return orderId;
    }
}

 

2. 이벤트 발행

@Service
@RequiredArgsConstructor
public class OrderService {

    private final ApplicationEventPublisher publisher;
    private final OrderRepository orderRepository;

    @Transactional
    public void completeOrder(Long orderId) {
        Order order = orderRepository.findById(orderId).orElseThrow();
        order.complete();

        publisher.publishEvent(new OrderCompletedEvent(orderId)); // 트랜잭션 내에서 발행
    }
}

 

3. 이벤트 리스너

@Component
public class OrderEventListener {

    @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
    public void handleOrderCompleted(OrderCompletedEvent event) {
        System.out.println("주문 완료 이벤트 처리, ID: " + event.getOrderId());
        // 이메일 전송, 포인트 적립 등 부가 처리
    }
}

3️⃣ TransactionPhase 종류

옵션 설명
AFTER_COMMIT (기본값) 트랜잭션이 성공적으로 커밋된 후 실행
AFTER_ROLLBACK 트랜잭션이 롤백된 후 실행
AFTER_COMPLETION 커밋 또는 롤백 모두 포함한 트랜잭션 종료 후 실행
BEFORE_COMMIT 트랜잭션이 커밋되기 직전 실행

4️⃣ 사용 시 주의사항

  • 이벤트 발행은 반드시 트랜잭션 안에서 일어나야 @TransactionalEventListener가 작동
  • 트랜잭션이 성공적으로 커밋되지 않으면, AFTER_COMMIT 이벤트는 실행되지 않음
  • 리스너에서 추가로 트랜잭션이 필요한 작업을 하려면 @Transactional을 명시적으로 사용