diff --git a/mobile/shop/orderformupdate.php b/mobile/shop/orderformupdate.php index 78a823b18..4c11d57f0 100644 --- a/mobile/shop/orderformupdate.php +++ b/mobile/shop/orderformupdate.php @@ -750,8 +750,33 @@ if(!$result) { } // 회원이면서 포인트를 사용했다면 포인트 테이블에 사용을 추가 -if ($is_member && $od_receipt_point) - insert_point($member['mb_id'], (-1) * $od_receipt_point, "주문번호 $od_id 결제"); +// 동시 주문 race condition 방지 — 회원 단위 GET_LOCK + 잔액 재조회 +if ($is_member && $od_receipt_point) { + $point_lock_key = 'g5pt_order_'.md5($member['mb_id']); + $lock_row = sql_fetch(" select get_lock('$point_lock_key', 5) as lk "); + + if (!empty($lock_row['lk'])) { + $current_point = (int) get_point_sum($member['mb_id']); + + if ($current_point >= $od_receipt_point) { + insert_point($member['mb_id'], (-1) * $od_receipt_point, "주문번호 $od_id 결제"); + } else { + // race condition 으로 잔액 부족 — 사용 가능한 만큼만 차감하고 부족분은 미수금 처리 + $actual_point = $current_point > 0 ? $current_point : 0; + $shortage = $od_receipt_point - $actual_point; + + if ($actual_point > 0) { + insert_point($member['mb_id'], (-1) * $actual_point, "주문번호 $od_id 결제"); + } + sql_query(" update {$g5['g5_shop_order_table']} + set od_receipt_point = '$actual_point', + od_misu = od_misu + '$shortage' + where od_id = '$od_id' "); + } + + sql_query(" do release_lock('$point_lock_key') "); + } +} $od_memo = nl2br(htmlspecialchars2(stripslashes($od_memo))) . " "; diff --git a/shop/orderformupdate.php b/shop/orderformupdate.php index a63af34b7..7d5912046 100644 --- a/shop/orderformupdate.php +++ b/shop/orderformupdate.php @@ -704,8 +704,33 @@ if(!$result) { } // 회원이면서 포인트를 사용했다면 테이블에 사용을 추가 -if ($is_member && $od_receipt_point) - insert_point($member['mb_id'], (-1) * $od_receipt_point, "주문번호 $od_id 결제"); +// 동시 주문 race condition 방지 — 회원 단위 GET_LOCK + 잔액 재조회 +if ($is_member && $od_receipt_point) { + $point_lock_key = 'g5pt_order_'.md5($member['mb_id']); + $lock_row = sql_fetch(" select get_lock('$point_lock_key', 5) as lk "); + + if (!empty($lock_row['lk'])) { + $current_point = (int) get_point_sum($member['mb_id']); + + if ($current_point >= $od_receipt_point) { + insert_point($member['mb_id'], (-1) * $od_receipt_point, "주문번호 $od_id 결제"); + } else { + // race condition 으로 잔액 부족 — 사용 가능한 만큼만 차감하고 부족분은 미수금 처리 + $actual_point = $current_point > 0 ? $current_point : 0; + $shortage = $od_receipt_point - $actual_point; + + if ($actual_point > 0) { + insert_point($member['mb_id'], (-1) * $actual_point, "주문번호 $od_id 결제"); + } + sql_query(" update {$g5['g5_shop_order_table']} + set od_receipt_point = '$actual_point', + od_misu = od_misu + '$shortage' + where od_id = '$od_id' "); + } + + sql_query(" do release_lock('$point_lock_key') "); + } +} $od_memo = nl2br(htmlspecialchars2(stripslashes($od_memo))) . " ";