배경
현재 환불 재시도 스케줄러는 재시도 대상 환불을 조회한 뒤 PG 취소를 처리합니다. 여러 애플리케이션 인스턴스가 동시에 실행되는 환경에서는 동일한 환불을 각 인스턴스가 함께 조회·처리할 수 있습니다. Toss의 멱등 키가 이중 환불을 완화하더라도 상태 전이, 환불 이력, retryCount가 중복 반영될 위험이 있습니다.
또한 최대 재시도 횟수에 도달한 환불에 대해 운영자가 인지하고 후속 조치할 수 있는 알림·지표 또는 데드레터 처리 경로가 필요합니다.
작업 내용
- 재시도 대상 환불을 PG 취소 호출 전에 원자적으로 선점(claim)하도록 처리합니다.
- 구현 방식은 DB 비관적 잠금/
SKIP LOCKED, 조건부 nextAttemptAt 갱신, 분산 락 등 현재 인프라와 데이터베이스 특성에 적합한 방식을 선택합니다.
- 다중 인스턴스가 같은
refundId를 동시에 처리하지 않도록 보장합니다.
- 기존 재시도 조건(
UNKNOWN, FAILURE, retryCount < 3, nextAttemptAt <= now)과 재시도 제한을 유지합니다.
- 최대 재시도 횟수 초과 또는 최종 실패 환불을 식별할 수 있도록 알림, 메트릭, 데드레터 중 적절한 운영 대응을 추가합니다.
- 동시 실행 환경에서 중복 PG 취소 요청 및 중복 상태/이력 갱신이 발생하지 않음을 검증하는 테스트를 추가합니다.
영향 범위
src/main/java/com/kosa/fillinv/payment/application/RefundRetryScheduler.java
src/main/java/com/kosa/fillinv/payment/repository/RefundRepository.java
- 환불 상태 전이·이력·재시도 관련 서비스 및 테스트
완료 조건
- 여러 인스턴스/동시 스케줄 실행 상황에서도 하나의 환불은 한 워커만 선점하여 PG 취소를 실행한다.
- 선점에 실패한 워커는 해당 환불을 처리하지 않는다.
- 재시도 한도 정책은 유지된다.
- 한도를 초과한 환불이 운영 관점에서 조회·감지 또는 후속 처리 가능하다.
- 관련 단위/통합 테스트가 추가되어 동시성 및 한도 초과 동작을 검증한다.
참고
배경
현재 환불 재시도 스케줄러는 재시도 대상 환불을 조회한 뒤 PG 취소를 처리합니다. 여러 애플리케이션 인스턴스가 동시에 실행되는 환경에서는 동일한 환불을 각 인스턴스가 함께 조회·처리할 수 있습니다. Toss의 멱등 키가 이중 환불을 완화하더라도 상태 전이, 환불 이력,
retryCount가 중복 반영될 위험이 있습니다.또한 최대 재시도 횟수에 도달한 환불에 대해 운영자가 인지하고 후속 조치할 수 있는 알림·지표 또는 데드레터 처리 경로가 필요합니다.
작업 내용
SKIP LOCKED, 조건부nextAttemptAt갱신, 분산 락 등 현재 인프라와 데이터베이스 특성에 적합한 방식을 선택합니다.refundId를 동시에 처리하지 않도록 보장합니다.UNKNOWN,FAILURE,retryCount < 3,nextAttemptAt <= now)과 재시도 제한을 유지합니다.영향 범위
src/main/java/com/kosa/fillinv/payment/application/RefundRetryScheduler.javasrc/main/java/com/kosa/fillinv/payment/repository/RefundRepository.java완료 조건
참고