|
@@ -16,11 +16,10 @@ import org.redisson.api.RQueue;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
import org.slf4j.LoggerFactory;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
+import org.springframework.data.redis.core.script.DefaultRedisScript;
|
|
import org.springframework.stereotype.Component;
|
|
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;
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
|
|
@Component
|
|
@Component
|
|
@@ -176,13 +175,35 @@ public class ApplyTaskCacheService implements CacheConstants {
|
|
*/
|
|
*/
|
|
public boolean decreaseApplyAvailableCount(Long examSiteId, Long timePeriodId) {
|
|
public boolean decreaseApplyAvailableCount(Long examSiteId, Long timePeriodId) {
|
|
String cacheKey = String.format(CACHE_APPLY_AVAILABLE_COUNT, examSiteId, 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;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|