역할
- 트랜잭션 상태에 따라 이벤트 핸들러를 실행할 수 있음.
예시 상황
- 트랜잭션이 성공적으로 커밋된 후에만 이벤트 핸들러를 실행하도록 설정할 수 있다.
- 트랜잭션 중 발생한 이벤트가 실제로 데이터베이스에 반영된 후에 처리되어야 할 때 유용
어노테이션 사용
@TransactionalEventListener
phase
속성을 통해 트랜잭션의 어떤 단계에서 이벤트 핸들러를 실행할지를 지정할 수 있습니다.
TransactionPhase
열거형( ENUM )을 사용하여 다음과 같은 단계를 지정할 수 있다.
BEFORE_COMMIT
: 트랜잭션이 커밋되기 바로 전에 실행됩니다.
AFTER_COMMIT
: 트랜잭션이 성공적으로 커밋된 후에 실행됩니다.
AFTER_ROLLBACK
: 트랜잭션이 롤백된 후에 실행됩니다.
AFTER_COMPLETION
: 트랜잭션이 커밋되거나 롤백된 후에 실행됩니다.
코드 예시
import org.springframework.transaction.event.TransactionPhase;
import org.springframework.transaction.event.TransactionalEventListener;
import org.springframework.stereotype.Service;
@Service
public class OrderCanceledEventHandler {
private RefundService refundService;
public OrderCanceledEventHandler(RefundService refundService) {
this.refundService = refundService;
}
@TransactionalEventListener(
classes = OrderCanceledEvent.class,
phase = TransactionPhase.AFTER_COMMIT
)
public void handle(OrderCanceledEvent event) {
refundService.refund(event.getOrderNumber());
}
}
OrderCanceledEvent
가 발생시
- 트랜잭션이 커밋된 이후에 handle → 환불이벤트가 수행된다.
- 사진상으로보면 … 비동기로 처리되는 경우
- DB 업데이트와 환불 관련 결제 취소 api 호출이 거의 동시에 이루어지게 되는데 일단 API 가 취소되는 것과 db 업데이트 되는 것 중에 DB업데이트가 먼저 되고 나서
- 해당 이벤트가 수행되어야 하기 때문에 페이스 단계를
AFTER COMMIT
으로 설정하게 되는 것입니다
- 만약에 트랜잭션이
롤백되면
이벤트 핸들러는 실행되지 않는다.
- 이를 통해 데이터 일관성 유지 및 트랜잭션 중에 발생할 수 있는 문제를 방지할 수 있다.
- 사진상으로보면 … 비동기로 처리되는 경우
Uploaded by N2T
'자바 > 리팩토링' 카테고리의 다른 글
[프로젝트] Springcloud Open Feign 으로 주소 API 를 호출해보자 (0) | 2024.02.13 |
---|---|
[프로젝트] 주문 생성시 Location 헤더와 HTTP 상태코드 201 Created 를 반환하는 건 어떨까? (0) | 2024.02.12 |
__mysql 5.7 에서 H2 1.4.200 호환을 위한 SCHEMA 수정__ (0) | 2024.02.07 |
@MybatisTest 클래스 레벨의 @Sql 이 수행되지 않는 경우 (0) | 2024.02.06 |
[프로젝트] 모킹 클래스의 private 필드에 테스트 데이터 삽입 방법 - `ReflectionTestUtils` (0) | 2024.02.04 |