deason 8 ماه پیش
والد
کامیت
37a9503400
1فایلهای تغییر یافته به همراه30 افزوده شده و 9 حذف شده
  1. 30 9
      src/main/java/com/qmth/exam/reserve/cache/impl/ApplyTaskCacheService.java

+ 30 - 9
src/main/java/com/qmth/exam/reserve/cache/impl/ApplyTaskCacheService.java

@@ -16,11 +16,10 @@ import org.redisson.api.RQueue;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.script.DefaultRedisScript;
 import org.springframework.stereotype.Component;
 
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 import java.util.concurrent.TimeUnit;
 
 @Component
@@ -176,13 +175,35 @@ public class ApplyTaskCacheService implements CacheConstants {
      */
     public boolean decreaseApplyAvailableCount(Long examSiteId, Long timePeriodId) {
         String cacheKey = String.format(CACHE_APPLY_AVAILABLE_COUNT, examSiteId, timePeriodId);
-        RAtomicLong atomic = redisClient.getRedissonClient().getAtomicLong(cacheKey);
-        if (atomic.decrementAndGet() >= 0) {
-            return true;
+
+        StringBuilder luaScript = new StringBuilder();
+        luaScript.append("local key = KEYS[1];");
+        luaScript.append("if (redis.call('exists', key) == 1) then");
+        luaScript.append("   local stock = tonumber(redis.call('get', key));");
+        luaScript.append("   local amount = tonumber(ARGV[1]);");
+        luaScript.append("   if (stock >= amount) then");
+        luaScript.append("      return redis.call('decrby', key, amount);");
+        luaScript.append("   end;");
+        luaScript.append("   return -1;");
+        luaScript.append("end;");
+        luaScript.append("return -2;");
+        List<String> keys = Collections.singletonList(cacheKey);
+        List<Object> args = Collections.singletonList(1);
+
+        // 执行Lua脚本,传入键列表和参数列表
+        DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>(luaScript.toString(), Long.class);
+        Long result = redisClient.getRedisTemplate().execute(redisScript, keys, args.toArray(new Object[0]));
+        Objects.requireNonNull(result, "缓存操作异常,返回结果为空!");
+
+        if (-2 == result) {
+            log.warn("扣减失败,考点剩余可约数量缓存不存在!cacheKey:{}", cacheKey);
+            return false;
+        } else if (-1 == result) {
+            log.warn("扣减失败,考点剩余可约数量为0不足!cacheKey:{}", cacheKey);
+            return false;
         }
-        // 允许最小减到0,否则减操作失败,退回一个数量
-        atomic.incrementAndGet();
-        return false;
+        log.info("扣减成功,最新考点剩余可约数量:{} cacheKey:{}", result, cacheKey);
+        return true;
     }
 
     /**