관리 메뉴

ballqs 님의 블로그

[Spring] @TransactionalEventListener란? 본문

코딩 공부/Spring

[Spring] @TransactionalEventListener란?

ballqs 2024. 9. 20. 23:40

@TransactionalEventListener란?

@TransactionalEventListener는 스프링에서 데이터베이스 트랜잭션의 경계를 따라 이벤트를 처리할 때 사용하는 특별한 어노테이션입니다. 이 어노테이션은 트랜잭션이 성공적으로 커밋된 이후에 이벤트가 처리되도록 보장합니다. 즉, 데이터베이스에 대한 작업이 확실히 완료된 후에만 이벤트가 실행되므로, 이벤트 핸들러에서 트랜잭션 내에서 발생한 변경사항을 신뢰할 수 있게 됩니다.


@EventListener와의 차이점

@EventListener는 트랜잭션과 관계없이 이벤트가 발생하면 즉시 처리됩니다. 반면에, @TransactionalEventListener는 트랜잭션의 상태에 따라 이벤트를 처리할 시점을 결정할 수 있습니다. 이를 통해 트랜잭션이 실패하면 이벤트 처리도 취소되며, 성공하면 비로소 이벤트가 처리됩니다.


트랜잭션 단계 설정

  • TransactionPhase.BEFORE_COMMIT: 트랜잭션이 커밋되기 전에 이벤트 처리.
  • TransactionPhase.AFTER_COMMIT: 트랜잭션이 성공적으로 커밋된 후에 이벤트 처리.
  • TransactionPhase.AFTER_ROLLBACK: 트랜잭션이 롤백된 후에 이벤트 처리.
  • TransactionPhase.AFTER_COMPLETION: 트랜잭션 완료 후, 커밋 또는 롤백 여부와 관계없이 이벤트 처리.

사용 예시

CartDetailEvent.java 작성

@AllArgsConstructor
@Getter
public class CartDetailEvent {
    private CartDetail cartDetail;
}

 

CartService.java 작성

@Slf4j(topic = "CartService")
@RequiredArgsConstructor
@Service
public class CartService {

    private final ApplicationEventPublisher eventPublisher;

    @Transactional
    public void createCart(Long userId , CartRequestInsertDto cartRequestInsertDto) {
        // ... 내용들
        CartDetail cartDetail = new CartDetail();
        eventPublisher.publishEvent(new CartDetailEvent(cartDetail));
    }
}

 

CartDetailService.java 작성

@Slf4j(topic = "CartDetailService")
@RequiredArgsConstructor
@Service
public class CartDetailService {

    private final CartDetailRepository cartDetailRepository;
    
    @TransactionalEventListener(phase = TransactionPhase.BEFORE_COMMIT)
    public void saveCartDetail(CartDetailEvent event) {
        cartDetailRepository.save(event.getCartDetail());
    }
}

주의할 점

  • @TransactionalEventListener는 반드시 트랜잭션 내에서 실행되어야 의미가 있습니다. 트랜잭션이 없는 경우에는 동작하지 않습니다.
  • 이벤트는 비동기로 처리될 수 있으므로, 필요한 경우 @Async와 함께 사용할 수 있습니다.