Skip to content

동시 환불 요청에 대한 중복 생성 경합 방지 #14

Description

@coderabbitai

개요

동일 결제(paymentId)에 대한 환불 요청이 동시에 들어오는 경우, 중복 환불 레코드가 생성되고 PG 취소가 중복 실행될 수 있는 경합 조건(TOCTOU)을 방지합니다.

배경

현재 RefundServiceRefundRepository.existsByPaymentId(...)로 중복 여부를 확인한 뒤 환불을 저장합니다. 두 요청이 동시에 해당 검증을 통과하면 각각 저장될 수 있으므로, 애플리케이션 레벨 검증만으로는 중복을 완전히 차단할 수 없습니다.

변경 사항

  • refunds.payment_id에 유니크 제약을 추가합니다.
  • 환불 저장 시 발생하는 DataIntegrityViolationException을 기존의 중복 환불 요청을 의미하는 ResourceException.InvalidArgument으로 변환합니다.
  • 동시 요청 상황에서도 하나만 저장되고, 나머지는 일관된 중복 요청 오류로 반환되는지 테스트합니다.

영향 범위

  • src/main/java/com/kosa/fillinv/payment/service/RefundService.java
  • src/main/java/com/kosa/fillinv/payment/repository/RefundRepository.java
  • Refund 엔티티 및 DB 마이그레이션/스키마 정의
  • 환불 요청 서비스 및 통합 테스트

완료 기준

  • DB 레벨에서 동일 payment_id 환불 레코드를 둘 이상 저장할 수 없다.
  • 유니크 제약 위반은 클라이언트에 중복 환불 요청 오류로 일관되게 반환된다.
  • 동시 환불 요청 테스트에서 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