카테고리 없음

오늘의 문제는 중복 쿠폰 발급되게 하기 입니다.

gw1 2025. 10. 9. 21:27

dbms 마다 차이가 있을 수 있으므로
mysql 기준으로 합니다.

CREATE TABLE coupon (
  coupon_code VARCHAR(20) PRIMARY KEY,  -- 쿠폰코드 (유니크)
  duplicate ENUM('Y','N') DEFAULT 'N'      -- 중복 발급 허용 여부
);

CREATE TABLE coupon_user (
  id BIGINT AUTO_INCREMENT PRIMARY KEY,
  coupon_code VARCHAR(20) NOT NULL,
  user_id BIGINT NOT NULL,
  issued_at DATETIME DEFAULT CURRENT_TIMESTAMP,
  UNIQUE (coupon_code, user_id)   -- 동일 유저가 같은 쿠폰 중복 발급 방지
);

기존 시스템은 (coupon_user, user_id) 유니크 제약 조건으로 중복 쿠폰을 막았으나

coupon에 duplicate 중복 발급 가능 여부 칼럼이 추가되어

(coupon_code, user_id) 값을

N인 쿠폰은 기존과 같이 중복 발급 불가

Y인 쿠폰은 중복 삽입이 가능하도록

시스템을 변경하고자 합니다.


트랜잭션 시작(리드커밋)

SELECT duplicate 
FROM coupon 
WHERE coupon_code = ?
// 중복 발급 체크

SELECT count(*) 
FROM coupon_user
WHERE coupon_code = ?
AND user_id = ?;

// 중복발급 막을 경우 count가 0개 인지 체크 

INSERT into coupon_user VALUES ~;

트랜잭션 커밋

위 코드는 동시성 문제가 발생하지만,

기존의 유니크 제약 조건으로 인해 문제가 생기지 않았습니다.

그러나, 중복 발급을 허용하게 되면서 (coupon_code, user_id)

해당 유니크 제약 조건을 삭제해야하는 상황에 처했습니다.

어떻게 풀어나갈지 서술하시오.

특정 쿠폰에 여러 사람이 몰릴 수 있습니다.(성능문제)

자기 자신이 짧은 시간에 수많은 요청해도 N일때
중복 발급되면 안됩니다(동시성정합성)

최대한 성능이 좋은 방식을 택하고

반드시 동시성에 대해 안전해야합니다.