@EventListener 의 경우 event 를 pulish 하는 코드 시점에 바로 event 가 발행됩니다. 그런데 event 를 발행되는 트랜잭션과 이벤트가 함께 생명주기를 가져가야하는 경우가 종종 있습니다. 그런 경우는 @EventListener 의 사용이 애매해집니다.
예를 들어, 회원의 업체 신청
을 관리자가 승인해주면 업체 신청
의 상태가 승인으로 바뀌고, 회원
권한이 업체로 바뀌고 업체
테이블이 하나 새로 등록되는 로직이 있다고 해봅시다. 관리자가 승인을 해주어 업체 신청
엔티티의 상태가 승인으로 바뀌면, 회원
권한을 바꿔주고 업체
테이블이 추가가 되는 이벤트를 발행해야겠죠. 이 세 로직의 결과는 모두 한번에 성공하거나 한번에 실패하거나여야 합니다. 하지만 @EventListener 를 쓰면 어떤 것은 성공하고 어떤 것은 실패할 수 있겠죠? 이런 경우 @TransactionListener 를 사용할 수 있습니다.
@TrasactionEventListener 는 event 의 발생을 트랜잭션의 상태를 기준으로 삼습니다. 그 상태를 지정해주는 여러 옵션이 있는데 아래와 같습니다.
앞서 말한 예시를 한번 코드의 간단한 사용 예를 살펴보도록 합시다.
@Transactional
public void changeEnrollmentStatus(Long enrollmentId, EnrollmentStatus status) {
applicationEventPublisher.publishEvent(new EnrollmentStatusEvent(enrollmentId, status));
enrollmentService.changeEnrollmentStatus(enrollmentId, status);
}
바꾸고자 하는 업체 신청
엔티티의 상태를 바꿔주고 이벤트를 발행하는 코드입니다.
@Getter
@RequiredArgsConstructor
public class EnrollmentStatusEvent {
private final Long enrollmentId;
private final EnrollmentStatus requestStatus;
public boolean isApproved() {
return this.requestStatus == EnrollmentStatus.APPROVED;
}
}