Skip to content

환불 재시도 스케줄러의 다중 인스턴스 중복 처리 방지 및 재시도 초과 운영 대응 #13

Description

@coderabbitai

배경

현재 환불 재시도 스케줄러는 재시도 대상 환불을 조회한 뒤 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 취소를 실행한다.
  • 선점에 실패한 워커는 해당 환불을 처리하지 않는다.
  • 재시도 한도 정책은 유지된다.
  • 한도를 초과한 환불이 운영 관점에서 조회·감지 또는 후속 처리 가능하다.
  • 관련 단위/통합 테스트가 추가되어 동시성 및 한도 초과 동작을 검증한다.

참고

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions