쿠폰 다운로드 포인트 검사를 회원 단위로 직렬화

기존에는 쿠폰별로 잠금을 잡아, 같은 회원이 서로 다른 포인트 쿠폰을
동시에 요청하면 각 요청이 요청 시작 시점의 보유 포인트 값으로 검사를
통과하여 잔액보다 많은 쿠폰을 받을 수 있었다.

- 잠금 범위를 쿠폰별에서 회원별로 변경
- 보유 포인트를 잠금 획득 후 회원 테이블에서 다시 조회하여 검사

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
(cherry picked from commit fd04b432cf34dfba52e281fc74391f8e2d48fe6b)
This commit is contained in:
thisgun
2026-08-24 07:44:22 +00:00
parent 42859072eb
commit 913d1c66c7
+10 -5
View File
@@ -19,7 +19,8 @@ if(!($cp['cz_start'] <= G5_TIME_YMD && $cp['cz_end'] >= G5_TIME_YMD))
die(json_encode(array('error' => '다운로드할 수 없는 쿠폰입니다.')));
// 동시 요청으로 인한 쿠폰 중복 발급 방지
$lock_key = 'g5_coupon_dl_'.$cz_id.'_'.addslashes($member['mb_id']);
// 포인트는 회원 단위 자원이므로 쿠폰이 달라도 같은 회원의 요청은 직렬화한다.
$lock_key = 'g5_coupon_dl_'.addslashes($member['mb_id']);
$lock_row = sql_fetch(" select get_lock('$lock_key', 5) as lk ");
if(empty($lock_row['lk']))
die(json_encode(array('error' => '잠시 후 다시 시도해 주십시오.')));
@@ -30,10 +31,14 @@ if(is_coupon_downloaded($member['mb_id'], $cp['cz_id'])) {
die(json_encode(array('error' => '이미 다운로드하신 쿠폰입니다.')));
}
// 포인트 쿠폰은 회원포인트 체크
if($cp['cz_type'] && ($member['mb_point'] - $cp['cz_point']) < 0) {
sql_query(" do release_lock('$lock_key') ");
die(json_encode(array('error' => '보유하신 포인트가 부족하여 쿠폰을 다운로드할 수 없습니다.')));
// 포인트 쿠폰은 회원포인트 체크 (락 획득 후 최신 잔액으로 재확인)
if($cp['cz_type']) {
$row_pt = sql_fetch(" select mb_point from {$g5['member_table']} where mb_id = '{$member['mb_id']}' ");
if(($row_pt['mb_point'] - $cp['cz_point']) < 0) {
sql_query(" do release_lock('$lock_key') ");
die(json_encode(array('error' => '보유하신 포인트가 부족하여 쿠폰을 다운로드할 수 없습니다.')));
}
}
// 쿠폰발급