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일때
중복 발급되면 안됩니다(동시성정합성)
최대한 성능이 좋은 방식을 택하고
반드시 동시성에 대해 안전해야합니다.