Jelajahi Sumber

修复重复发放优惠券问题

locky 8 bulan lalu
induk
melakukan
f1fd620038
2 mengubah file dengan 30 tambahan dan 15 penghapusan
  1. 28 15
      Controller/SysManage.py
  2. 2 0
      Object/Enums/RedisKeyConstant.py

+ 28 - 15
Controller/SysManage.py

@@ -144,24 +144,31 @@ def initMsgFunc(request):
     expire = end_time - now_time
     if (now_time > start_time and expire > 0) or userID in ConstantEnum.TEST_ACCOUNT_LIST.value:
         redis_obj = RedisObject()
-        distribute_key = RedisKeyConstant.CLOUD_STORAGE_COUPONS.value + userID
-        is_distributed = redis_obj.get_data(distribute_key)
-        if not is_distributed:
-            thread_kwargs = {
-                'user_id': userID,
-                'redis_obj': redis_obj,
-                'distribute_key': distribute_key,
-                'expire': expire,
-                'end_time': end_time
-            }
-            del_push_info_thread = threading.Thread(
-                target=distribute_cloud_storage_coupons,
-                kwargs=thread_kwargs)
-            del_push_info_thread.start()
+
+        # 加锁
+        grant_key = RedisKeyConstant.GRANT_COUPONS_LOCK.value + userID
+        lock_success = redis_obj.CONN.setnx(grant_key, 1)
+        if lock_success:
+            redis_obj.CONN.expire(grant_key, 600)
+            distribute_key = RedisKeyConstant.CLOUD_STORAGE_COUPONS.value + userID
+            is_distributed = redis_obj.get_data(distribute_key)
+            if not is_distributed:
+                thread_kwargs = {
+                    'user_id': userID,
+                    'redis_obj': redis_obj,
+                    'distribute_key': distribute_key,
+                    'expire': expire,
+                    'end_time': end_time,
+                    'grant_key': grant_key
+                }
+                del_push_info_thread = threading.Thread(
+                    target=distribute_cloud_storage_coupons,
+                    kwargs=thread_kwargs)
+                del_push_info_thread.start()
     return response.json(0, res)
 
 
-def distribute_cloud_storage_coupons(user_id, redis_obj, distribute_key, expire, end_time):
+def distribute_cloud_storage_coupons(user_id, redis_obj, distribute_key, expire, end_time,  grant_key):
     """
     发放云存优惠券
     满足条件,用户存在以下三种类型的设备:
@@ -173,6 +180,7 @@ def distribute_cloud_storage_coupons(user_id, redis_obj, distribute_key, expire,
     @param distribute_key: 发放优惠券缓存key
     @param expire: distribute_key过期时间
     @param end_time: 活动结束时间
+    @param grant_key: 发放锁
     @return:
     """
     try:
@@ -191,12 +199,14 @@ def distribute_cloud_storage_coupons(user_id, redis_obj, distribute_key, expire,
                         if not experience_qs.exists():
                             # 发放
                             generate_success = CouponView.generate_coupon_by_user(user_id)
+                            break
                         else:
                             # 体验过未购买过
                             orders_qs = Order_Model.objects.filter(UID=uid, status=1, payType__in=[1, 4, 5])
                             if not orders_qs.exists():
                                 # 发放
                                 generate_success = CouponView.generate_coupon_by_user(user_id)
+                                break
                             else:
                                 # 购买过且已过期
                                 # 没有未使用套餐,且过期时间在2024-12-29前
@@ -204,9 +214,12 @@ def distribute_cloud_storage_coupons(user_id, redis_obj, distribute_key, expire,
                                 if vod_uid_bucket_qs.exists():
                                     # 发放
                                     generate_success = CouponView.generate_coupon_by_user(user_id)
+                                    break
         if generate_success:
             redis_obj.set_data(distribute_key, '1', expire)
         else:
             redis_obj.set_data(distribute_key, '0', expire)
+        redis_obj.del_data(grant_key)
     except Exception as e:
+        redis_obj.del_data(grant_key)
         return

+ 2 - 0
Object/Enums/RedisKeyConstant.py

@@ -16,6 +16,8 @@ class RedisKeyConstant(Enum):
     COUPON_ID_LOCK = 'COUPON:ID:LOCK:'
     # 云存优惠券
     CLOUD_STORAGE_COUPONS = 'cloud_storage_coupons_'
+    # 发放优惠券锁
+    GRANT_COUPONS_LOCK = 'grant_coupons_lock_'
     # 基础模块用户优惠券
     BASIC_CLOUD_COUPON = 'BASIC:CLOUD:COUPON:'