1. 왜 사용하는지?
결제 승인과 같은 핵심 비즈니스 로직 하나의 트랜잭션으로 동작
-> 결제 실패시 retryCount 증가
재시도를 위한 상태 정보 반드시 저장되어야하는데
부모 트랜잭션에서 수행하면 부모 트랜잭션이 롤백될때 함께 롤백되는 문제가 발생합니다.
-> 현재 결제가 실패했더라도 다음 재시도를 가능하게 만들기 위해
2. 부모 트랜잭션에서 발생하는 문제
예를 들어 결제 승인 로직이 있다고 가정합니다.
@Transactional
public void confirm(Long orderId) {
Payment payment = paymentRepository.findById(orderId);
tossPaymentClient.confirm(payment);
payment.complete();
}
실행 과정
Transaction A
↓
결제 승인 요청
↓
Toss API 실패
↓
Exception 발생
↓
Transaction A Rollback
이제 retry 횟수를 저장하려고 합니다.
@Transactional
public void confirm(Long orderId) {
Payment payment = paymentRepository.findById(orderId);
try {
tossPaymentClient.confirm(payment);
payment.complete();
} catch (Exception e) {
payment.increaseRetry();
throw e;
}
}
언뜻 보면 retryCount가 증가하는 것처럼 보입니다.
하지만 실제로는
retryCount++
↓
Exception
↓
Transaction Rollback
↓
retryCount도 Rollback
즉
retryCount = 0
으로 다시 돌아갑니다.
이것이
부모 트랜잭션의 롤백에 휩쓸린다.
라는 의미입니다.
결론
REQUIRES_NEW는 현재 트랜잭션을 잠시 중단(Suspend)하고 새로운 독립 트랜잭션을 생성하는 전파 속성입니다.
결제 시스템, 메시지 처리 시스템, 배치 재시도 시스템에서 널리 사용하는 패턴이며, "실패한 비즈니스와 재시도 상태를 분리하여 관리한다"는 설계의도에서 사용됩니다.
'【Spring】' 카테고리의 다른 글
| [HttpClient] (0) | 2026.02.23 |
|---|---|
| [CacheManager ] (0) | 2026.02.20 |
| [spring AI] .content() 사용이유 (0) | 2025.10.22 |
| [@RequestParam] RequestParam의 순서 (0) | 2025.09.28 |
| [반환값] 어떤거를 반환값으로 받아야하는지에 대한 고찰 (0) | 2025.09.28 |