File tree Expand file tree Collapse file tree 1 file changed +8
-1
lines changed
app/eventyay/base/services Expand file tree Collapse file tree 1 file changed +8
-1
lines changed Original file line number Diff line number Diff line change @@ -1000,7 +1000,9 @@ def _get_voucher_availability(self):
10001000 vouchers_ok = {}
10011001 self ._voucher_depend_on_cart = set ()
10021002 for voucher , count in self ._voucher_use_diff .items ():
1003- voucher .refresh_from_db ()
1003+ # Use pessimistic locking to prevent race conditions
1004+ # This ensures only one thread can check and modify voucher availability at a time
1005+ voucher = Voucher .objects .select_for_update ().get (pk = voucher .pk )
10041006
10051007 if voucher .valid_until is not None and voucher .valid_until < self .now_dt :
10061008 raise CartError (error_messages ['voucher_expired' ])
@@ -1010,6 +1012,11 @@ def _get_voucher_availability(self):
10101012 ).exclude (pk__in = [op .position .id for op in self ._operations if isinstance (op , self .ExtendOperation )])
10111013 cart_count = redeemed_in_carts .count ()
10121014 v_avail = voucher .max_usages - voucher .redeemed - cart_count
1015+
1016+ # Validate availability after acquiring lock to prevent over-redemption
1017+ if v_avail < count :
1018+ raise CartError (error_messages ['voucher_redeemed' ])
1019+
10131020 if cart_count > 0 :
10141021 self ._voucher_depend_on_cart .add (voucher )
10151022 vouchers_ok [voucher ] = v_avail
You can’t perform that action at this time.
0 commit comments