|
@@ -106,39 +106,6 @@ public class ApplyTaskCacheService implements CacheConstants {
|
|
|
log.warn("DELETE cacheKey:{}", cacheKey);
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * 获取某考点的“可预约总量”缓存
|
|
|
- */
|
|
|
- public int getApplyTotalCount(Long examSiteId) {
|
|
|
- String cacheKey = String.format(CACHE_APPLY_TOTAL, examSiteId);
|
|
|
- Integer value = redisClient.get(cacheKey, Integer.class);
|
|
|
- if (value != null) {
|
|
|
- return value;
|
|
|
- }
|
|
|
-
|
|
|
- value = examSiteService.countExamSiteCapacityById(examSiteId);
|
|
|
- redisClient.set(cacheKey, value, CACHE_TIME_OUT_10, TimeUnit.MINUTES);
|
|
|
- log.info("SET cacheKey:{} value:{}", cacheKey, value);
|
|
|
-
|
|
|
- return value;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 清除某考点的“可预约总量”缓存
|
|
|
- */
|
|
|
- public void clearApplyTotalCountCache(Long examSiteId) {
|
|
|
- String cacheKey = String.format(CACHE_APPLY_TOTAL, examSiteId);
|
|
|
- redisClient.delete(cacheKey);
|
|
|
- log.warn("DELETE cacheKey:{}", cacheKey);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取某考点某时段的“已预约数量”(查数据库)
|
|
|
- */
|
|
|
- public int getApplyFinishCountFormDB(Long examSiteId, Long timePeriodId) {
|
|
|
- return studentApplyService.countApplyFinishForExamSiteAndTimePeriod(examSiteId, timePeriodId);
|
|
|
- }
|
|
|
-
|
|
|
/**
|
|
|
* 获取某考点某时段的“剩余可约数量”缓存
|
|
|
*/
|
|
@@ -195,18 +162,16 @@ public class ApplyTaskCacheService implements CacheConstants {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 初始化 某考点某时段的“剩余可约数量”缓存
|
|
|
+ * 刷新 某考点某时段的“剩余可约数量”缓存
|
|
|
*/
|
|
|
- public void initApplyAvailableCountCache(Long examSiteId, int oldCapacity, int newCapacity) {
|
|
|
- String examSiteCapacityLockKey = String.format(CacheConstants.LOCK_EXAM_SITE_CAPACITY, examSiteId);
|
|
|
- Lock examSiteCapacityLock = concurrentService.getLock(examSiteCapacityLockKey);
|
|
|
+ public void refreshApplyAvailableCountCache(Long examSiteId, int oldCapacity, int newCapacity) {
|
|
|
+ String lockKey = String.format(CacheConstants.LOCK_EXAM_SITE_CAPACITY, examSiteId);
|
|
|
+ Lock lock = concurrentService.getLock(lockKey);
|
|
|
|
|
|
try {
|
|
|
- if (!examSiteCapacityLock.tryLock()) {
|
|
|
- log.warn("获取锁失败,不允许同时操作!lockKey:{}", examSiteCapacityLockKey);
|
|
|
- return;
|
|
|
+ if (!lock.tryLock()) {
|
|
|
+ throw new RuntimeException("获取锁失败,不允许同时操作!" + lockKey);
|
|
|
}
|
|
|
- log.debug("获取锁成功!lockKey:{}", examSiteCapacityLockKey);
|
|
|
|
|
|
// 获取所有时段ID集合
|
|
|
List<TimePeriodEntity> timePeriods = timePeriodService.list(new LambdaQueryWrapper<TimePeriodEntity>().select(TimePeriodEntity::getId));
|
|
@@ -224,35 +189,75 @@ public class ApplyTaskCacheService implements CacheConstants {
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
- // 总容量变化时,则更新考点剩余容量缓存
|
|
|
+ // 总容量变化时,则更新考点剩余可约数量缓存
|
|
|
RAtomicLong atomic = redisClient.getRedissonClient().getAtomicLong(cacheKey);
|
|
|
long availableCount = Math.max(atomic.get() + diffCapacity, 0);
|
|
|
atomic.set(availableCount);
|
|
|
log.warn("SET cacheKey:{} value:{}", cacheKey, availableCount);
|
|
|
} else {
|
|
|
- // 初始考点剩余容量缓存
|
|
|
+ // 初始考点剩余可约数量缓存
|
|
|
RAtomicLong atomic = redisClient.getRedissonClient().getAtomicLong(cacheKey);
|
|
|
atomic.set(newCapacity);
|
|
|
- log.debug("SET cacheKey:{} value:{}", cacheKey, newCapacity);
|
|
|
+ log.info("SET cacheKey:{} value:{}", cacheKey, newCapacity);
|
|
|
}
|
|
|
}
|
|
|
} finally {
|
|
|
try {
|
|
|
- examSiteCapacityLock.unlock();
|
|
|
- log.debug("解锁成功!lockKey:{}", examSiteCapacityLockKey);
|
|
|
+ lock.unlock();
|
|
|
} catch (Exception e) {
|
|
|
- log.warn("解锁失败!lockKey:{} err:{}", examSiteCapacityLockKey, e.getMessage());
|
|
|
+ log.warn("解锁失败!lockKey:{} err:{}", lockKey, e.getMessage());
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 初始化 所有考点所有时段的“剩余可约数量”缓存
|
|
|
+ * 初始或重置计算 所有考点所有时段的“剩余可约数量”缓存
|
|
|
*/
|
|
|
- public void initApplyAvailableCountCacheForAllExamSites() {
|
|
|
+ public void initApplyAvailableCountCacheForAllExamSites(boolean skipExisted) {
|
|
|
+ // 获取所有考点和考点总容量集合
|
|
|
List<ExamSiteCapacityInfo> examSites = examSiteService.findAllExamSiteCapacityList();
|
|
|
+ if (CollectionUtils.isEmpty(examSites)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取所有时段ID集合
|
|
|
+ List<TimePeriodEntity> timePeriods = timePeriodService.list(new LambdaQueryWrapper<TimePeriodEntity>().select(TimePeriodEntity::getId));
|
|
|
+ if (CollectionUtils.isEmpty(timePeriods)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
for (ExamSiteCapacityInfo examSite : examSites) {
|
|
|
- this.initApplyAvailableCountCache(examSite.getExamSiteId(), examSite.getCapacity(), examSite.getCapacity());
|
|
|
+ String lockKey = String.format(CacheConstants.LOCK_EXAM_SITE_CAPACITY, examSite.getExamSiteId());
|
|
|
+ Lock lock = concurrentService.getLock(lockKey);
|
|
|
+
|
|
|
+ try {
|
|
|
+ if (!lock.tryLock()) {
|
|
|
+ log.warn("获取锁失败,不允许同时操作!{}", lockKey);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (TimePeriodEntity timePeriod : timePeriods) {
|
|
|
+ String cacheKey = String.format(CACHE_APPLY_AVAILABLE_COUNT, examSite.getExamSiteId(), timePeriod.getId());
|
|
|
+ if (redisClient.exist(cacheKey) && skipExisted) {
|
|
|
+ // 跳过存在的缓存
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取某考点某时段的“已预约数量”(仅查数据库会有误差,需等预约队列中全部完成数据库持久化后再执行!)
|
|
|
+ int finishCount = studentApplyService.countApplyFinishForExamSiteAndTimePeriod(examSite.getExamSiteId(), timePeriod.getId());
|
|
|
+ // 剩余可约数量
|
|
|
+ int availableCount = Math.max(examSite.getCapacity() - finishCount, 0);
|
|
|
+ RAtomicLong atomic = redisClient.getRedissonClient().getAtomicLong(cacheKey);
|
|
|
+ atomic.set(availableCount);
|
|
|
+ log.warn("SET cacheKey:{} value:{}", cacheKey, availableCount);
|
|
|
+ }
|
|
|
+ } finally {
|
|
|
+ try {
|
|
|
+ lock.unlock();
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("解锁失败!lockKey:{} err:{}", lockKey, e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|