Skip to content

[Volume 4] 쿠폰 추가, 동시성 제어 적용#170

Open
simoncho91 wants to merge 11 commits intoLoopers-dev-lab:ymchofrom
simoncho91:order_lock
Open

[Volume 4] 쿠폰 추가, 동시성 제어 적용#170
simoncho91 wants to merge 11 commits intoLoopers-dev-lab:ymchofrom
simoncho91:order_lock

Conversation

@simoncho91
Copy link

@simoncho91 simoncho91 commented Mar 6, 2026

📌 Summary

  • 쿠폰 도메인 구현 (CouponTemplate / IssuedCoupon 분리 설계)
  • 주문 시 쿠폰 적용 흐름 통합 (할인 계산, 주문 스냅샷 저장)
  • 재고 차감 / 쿠폰 사용에 비관적 락 적용으로 동시성 이슈 해결
  • 데드락 방지를 위한 락 획득 순서 설계 (쿠폰 → 상품, 상품은 ID 오름차순)
  • 동시성 통합 테스트 3종 작성 (재고 / 쿠폰 / 좋아요)

🧭 Context & Decision

문제 정의

  • 현재 동작/제약: 주문 시 재고 차감과 쿠폰 사용이 각각 독립적으로 처리되어 동시 요청 시 정합성이 보장되지 않음
  • 문제(또는 리스크):
    • 재고 10개 상품에 10명이 동시 주문하면 Lost Update로 초과 판매 가능
    • 같은 쿠폰으로 여러 기기에서 동시 주문하면 1회 사용 제약이 깨질 수 있음
  • 성공 기준: 동시성 테스트에서 재고/쿠폰/좋아요 모두 정합성 유지, 쿠폰은 정확히 1건만 성공

선택지와 결정

  • 재고 차감 락 전략
  • A. 낙관적 락(@Version): 충돌 감지 후 재시도. 경합이 적을 때 유리하나, 재고처럼 동시 요청이 많으면 대부분 실패 후 재시도 → 사용자 경험 저하
  • B. 비관적 락(PESSIMISTIC_WRITE): 조회 시점에 행 잠금 획득. 충돌을 사전 차단
  • 결정: 비관적 락 >>
  • 트레이드오프: 락 보유 시간만큼 다른 트랜잭션 대기 발생. 단일 상품 기준으로는 허용 가능한 수준
  • 쿠폰 사용 락 전략
  • A. 낙관적 락: 커밋 시점에 충돌 감지. 이미 재고 차감 등 후속 작업을 수행한 뒤 실패 → 불필요한 롤백 비용
  • B. 비관적 락: 조회 시점에 독점권 확보. 유효하지 않은 요청을 재고 차감 전에 차단 가능
  • 결정: 비관적 락 >>
  • 트레이드오프: 쿠폰 1건에 대한 동시 요청 빈도는 낮아 대기 비용 미미
  • 좋아요
  • DB Unique(member_id, product_id)로 해결. 별도 락 불필요

  • 트레이드오프: 멱등성 보장이 목적이므로 제약조건이 가장 효율적이라고 생각함

  • 추후 개선 여지: 재고가 매우 빈번하게 변경되는 경우 Redis 기반 분산 락으로 전환 고려 가능

🏗️ Design Overview

변경 범위

  • 영향 받는 모듈/도메인: order, coupon, product
  • 신규 추가: CouponTemplate, IssuedCoupon, CouponService, CouponAdminService, CouponFacade, Admin/User API
  • 제거/대체: OrderDomainService.placeOrder() → prepareOrderLines() + createOrder() / createOrderWithCoupon()으로 분리

주요 컴포넌트 책임

  • CouponTemplate: 할인 정책 정의. calculateDiscount(), validateMinOrderAmount(), isExpired() 등 할인 규칙 캡슐화
  • IssuedCoupon: 발급 인스턴스. use()로 AVAILABLE → USED 상태 전이 규칙 캡슐화, 소유자 검증
  • OrderDomainService: productId 오름차순 정렬 후 비관적 락 획득 및 재고 차감, 주문 엔티티 생성
  • OrderService: 트랜잭션 경계. 쿠폰 락 → 재고 락 → 할인 계산 → 주문 생성 → 쿠폰 사용 흐름 조율
  • Order: originalAmount / discountAmount / couponId 스냅샷 저장. 주문 이후 가격/정책 변경에 무관하게 결제 금액 유지

hanyoung-kurly and others added 11 commits February 2, 2026 01:26
- 유효한 정보로 회원 생성 성공 테스트
- 각 필드 null/blank 검증 테스트
- loginId, password, name, birthDate, email 필수값 검증
- 필수 필드 5개 (loginId, encryptedPassword, name, birthDate, email)
- 생성자에서 각 필드 null/blank 검증
- BaseEntity 상속으로 id, 생성/수정 시간 자동 관리
- 비밀번호 암호화는 추후 구현 예정
fix : 예제 테스트 코드 오류 해결을 위한 testcontainers 버전 업
- Coupon 도메인 신규 구현 (CouponTemplate, IssuedCoupon, 정액/정률 할인)
- 쿠폰 사용자 API (발급, 내 쿠폰 조회) 및 Admin CRUD API 구현
- 주문 흐름에 쿠폰 할인 통합 (originalAmount, discountAmount, totalAmount 스냅샷)
- Product 재고 차감에 비관적 락(PESSIMISTIC_WRITE) 적용
- IssuedCoupon 사용 처리에 비관적 락 적용으로 동시 사용 방지
- 데드락 방지를 위해 상품 락 획득 시 productId 오름차순 정렬
- 동시성 통합 테스트 (재고 동시 차감, 쿠폰 동시 사용, 좋아요 동시 요청)
- 쿠폰 도메인 단위 테스트 및 주문-쿠폰 통합 서비스 테스트
- ErrorType 확장 (쿠폰 관련 에러 타입 추가)
- analyze-query SKILL.md 개선 (Lock/동시성 분석 섹션 추가)
- .cursor/rules/domain-coupon.mdc 규칙 추가

Made-with: Cursor
- OrderService: 트랜잭션 범위 설계 근거, 락 획득 순서, dirty checking 활용 주석 보강
- OrderDomainService: 비관적 락 선택 이유, 데드락 시나리오 및 정렬 전략 주석 추가
- ProductJpaRepository: 낙관적/비관적 락 trade-off 비교 주석 추가
- IssuedCouponJpaRepository: Lost Update 시나리오, 비관적 락 방지 흐름 주석 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link

coderabbitai bot commented Mar 6, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 84ed6e48-669c-42b8-8e2c-d89b2f445054

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@simoncho91 simoncho91 marked this pull request as ready for review March 6, 2026 08:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants