|
@@ -1,6 +1,7 @@
|
|
package com.qmth.exam.reserve.cache.impl;
|
|
package com.qmth.exam.reserve.cache.impl;
|
|
|
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
|
+import com.qmth.boot.core.concurrent.service.ConcurrentService;
|
|
import com.qmth.exam.reserve.bean.apply.ApplyRecordCacheBean;
|
|
import com.qmth.exam.reserve.bean.apply.ApplyRecordCacheBean;
|
|
import com.qmth.exam.reserve.bean.applytask.CurrentApplyTaskVO;
|
|
import com.qmth.exam.reserve.bean.applytask.CurrentApplyTaskVO;
|
|
import com.qmth.exam.reserve.bean.examsite.ExamSiteCapacityInfo;
|
|
import com.qmth.exam.reserve.bean.examsite.ExamSiteCapacityInfo;
|
|
@@ -21,6 +22,7 @@ import org.springframework.stereotype.Component;
|
|
|
|
|
|
import java.util.*;
|
|
import java.util.*;
|
|
import java.util.concurrent.TimeUnit;
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
+import java.util.concurrent.locks.Lock;
|
|
|
|
|
|
@Component
|
|
@Component
|
|
public class ApplyTaskCacheService implements CacheConstants {
|
|
public class ApplyTaskCacheService implements CacheConstants {
|
|
@@ -45,6 +47,9 @@ public class ApplyTaskCacheService implements CacheConstants {
|
|
@Autowired
|
|
@Autowired
|
|
private StudentApplyService studentApplyService;
|
|
private StudentApplyService studentApplyService;
|
|
|
|
|
|
|
|
+ @Autowired
|
|
|
|
+ private ConcurrentService concurrentService;
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* 获取当前启用的预约任务缓存
|
|
* 获取当前启用的预约任务缓存
|
|
*/
|
|
*/
|
|
@@ -193,33 +198,50 @@ public class ApplyTaskCacheService implements CacheConstants {
|
|
* 初始化 某考点某时段的“剩余可约数量”缓存
|
|
* 初始化 某考点某时段的“剩余可约数量”缓存
|
|
*/
|
|
*/
|
|
public void initApplyAvailableCountCache(Long examSiteId, int oldCapacity, int newCapacity) {
|
|
public void initApplyAvailableCountCache(Long examSiteId, int oldCapacity, int newCapacity) {
|
|
- // 获取所有时段ID集合
|
|
|
|
- List<TimePeriodEntity> timePeriods = timePeriodService.list(new LambdaQueryWrapper<TimePeriodEntity>().select(TimePeriodEntity::getId));
|
|
|
|
- if (CollectionUtils.isEmpty(timePeriods)) {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
|
|
+ String examSiteCapacityLockKey = String.format(CacheConstants.LOCK_EXAM_SITE_CAPACITY, examSiteId);
|
|
|
|
+ Lock examSiteCapacityLock = concurrentService.getLock(examSiteCapacityLockKey);
|
|
|
|
|
|
- // 新、旧考点容量差额
|
|
|
|
- int diffCapacity = newCapacity - oldCapacity;
|
|
|
|
|
|
+ try {
|
|
|
|
+ if (!examSiteCapacityLock.tryLock()) {
|
|
|
|
+ log.warn("获取锁失败,不允许同时操作!lockKey:{}", examSiteCapacityLockKey);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ log.debug("获取锁成功!lockKey:{}", examSiteCapacityLockKey);
|
|
|
|
|
|
- for (TimePeriodEntity timePeriod : timePeriods) {
|
|
|
|
- String cacheKey = String.format(CACHE_APPLY_AVAILABLE_COUNT, examSiteId, timePeriod.getId());
|
|
|
|
- if (redisClient.exist(cacheKey)) {
|
|
|
|
- if (diffCapacity == 0) {
|
|
|
|
- // 考点总容量未变化,不用更新缓存
|
|
|
|
- continue;
|
|
|
|
- }
|
|
|
|
|
|
+ // 获取所有时段ID集合
|
|
|
|
+ List<TimePeriodEntity> timePeriods = timePeriodService.list(new LambdaQueryWrapper<TimePeriodEntity>().select(TimePeriodEntity::getId));
|
|
|
|
+ if (CollectionUtils.isEmpty(timePeriods)) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
|
|
- // 总容量变化时,则更新考点剩余容量缓存
|
|
|
|
- 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);
|
|
|
|
|
|
+ // 新、旧考点容量差额
|
|
|
|
+ int diffCapacity = newCapacity - oldCapacity;
|
|
|
|
+ for (TimePeriodEntity timePeriod : timePeriods) {
|
|
|
|
+ String cacheKey = String.format(CACHE_APPLY_AVAILABLE_COUNT, examSiteId, timePeriod.getId());
|
|
|
|
+ if (redisClient.exist(cacheKey)) {
|
|
|
|
+ if (diffCapacity == 0) {
|
|
|
|
+ // 考点总容量未变化,不用更新缓存
|
|
|
|
+ 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);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ } finally {
|
|
|
|
+ try {
|
|
|
|
+ examSiteCapacityLock.unlock();
|
|
|
|
+ log.debug("解锁成功!lockKey:{}", examSiteCapacityLockKey);
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ log.warn("解锁失败!lockKey:{} err:{}", examSiteCapacityLockKey, e.getMessage());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|