ソースを参照

save&cancel StudentApply

deason 8 ヶ月 前
コミット
eeff75b2ae

+ 26 - 15
src/main/java/com/qmth/exam/reserve/cache/impl/ApplyTaskCacheService.java

@@ -153,20 +153,10 @@ public class ApplyTaskCacheService implements CacheConstants {
         return value;
     }
 
-    /**
-     * 获取当前预约时段剩余可约数量缓存
-     */
-    public int getApplyAvailableCount(Long examSiteId, Long timePeriodId) {
-        int totalCount = this.getApplyTotalCount(examSiteId);
-        int finishCount = this.getApplyFinishCount(examSiteId, timePeriodId);
-        int availableCount = totalCount - finishCount;
-        return Math.max(availableCount, 0);
-    }
-
     /**
      * 获取某考点某时段的“剩余可约数量”缓存
      */
-    public int getApplyAvailableCount2(Long examSiteId, Long timePeriodId) {
+    public int getApplyAvailableCount(Long examSiteId, Long timePeriodId) {
         String cacheKey = String.format(CACHE_APPLY_AVAILABLE_COUNT, examSiteId, timePeriodId);
         RAtomicLong atomic = redisClient.getRedissonClient().getAtomicLong(cacheKey);
         return (int) atomic.get();
@@ -184,12 +174,15 @@ public class ApplyTaskCacheService implements CacheConstants {
     /**
      * 累减 某考点某时段的“剩余可约数量”缓存
      */
-    public void decreaseApplyAvailableCount(Long examSiteId, Long timePeriodId) {
+    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.get() > 0) {
-            atomic.decrementAndGet();
+        if (atomic.decrementAndGet() >= 0) {
+            return true;
         }
+        // 允许最小减到0,否则减操作失败,退回一个数量
+        atomic.incrementAndGet();
+        return false;
     }
 
     /**
@@ -338,7 +331,25 @@ public class ApplyTaskCacheService implements CacheConstants {
     public ApplyRecordCacheBean getStudentApplyRecord(Long studentId, Long examSiteId, Long timePeriodId) {
         String cacheKey = String.format(CACHE_STUDENT_APPLY_RECORD, studentId);
         String hashKey = String.format("%s_%s", examSiteId, timePeriodId);
-        return redisClient.getForHash(cacheKey, hashKey, ApplyRecordCacheBean.class);
+        ApplyRecordCacheBean cacheBean = redisClient.getForHash(cacheKey, hashKey, ApplyRecordCacheBean.class);
+        if (cacheBean != null) {
+            return cacheBean;
+        }
+
+        // 缓存不存在时,从数据库再查一次
+        StudentApplyEntity entity = this.getStudentApplyRecordFormDB(studentId, examSiteId, timePeriodId);
+        if (entity != null) {
+            cacheBean = new ApplyRecordCacheBean();
+            cacheBean.setStudentId(entity.getStudentId());
+            cacheBean.setExamSiteId(entity.getExamSiteId());
+            cacheBean.setTimePeriodId(entity.getTimePeriodId());
+            cacheBean.setCancel(entity.getCancel());
+            cacheBean.setOperateId(entity.getOperateId());
+            cacheBean.setOperateTime(entity.getUpdateTime());
+            return cacheBean;
+        }
+
+        return null;
     }
 
     /**

+ 10 - 13
src/main/java/com/qmth/exam/reserve/service/impl/ExamReserveServiceImpl.java

@@ -146,29 +146,26 @@ public class ExamReserveServiceImpl implements ExamReserveService {
                 throw new StatusException(msg);
             }
 
-            // 当前预约时段剩余可约数量
-            int availableCount = applyTaskCacheService.getApplyAvailableCount(examSiteId, timePeriodId);
-            if (availableCount < 1) {
+            // 某考点某时段的“剩余可约数量” 累减1(抢占1个数量)
+            boolean takeSuccess = applyTaskCacheService.decreaseApplyAvailableCount(examSiteId, timePeriodId);
+            if (!takeSuccess) {
                 log.warn("预约失败,当前预约时段已约满!examSiteId:{} timePeriodId:{}", examSiteId, timePeriodId);
                 throw new StatusException("当前预约时段已约满");
             }
 
-            // 某考点某时段的“已预约数量” 累加1(优先执行抢占1个数量)
-            applyTaskCacheService.increaseApplyFinishCount(examSiteId, timePeriodId);
-
             try {
                 // StudentApplyEntity existApply = applyTaskCacheService.getStudentApplyRecordFormDB(student.getId(), examSiteId, timePeriodId);
                 ApplyRecordCacheBean existApply = applyTaskCacheService.getStudentApplyRecord(student.getId(), examSiteId, timePeriodId);
                 if (existApply != null) {
                     if (!existApply.getCancel()) {
-                        // 某考点某时段的“已预约数量” 累减1(释放1个被占数量)
-                        applyTaskCacheService.decreaseApplyFinishCount(examSiteId, timePeriodId);
+                        // 已存在预约记录,则归还1个刚才被占数量
+                        applyTaskCacheService.increaseApplyAvailableCount(examSiteId, timePeriodId);
 
                         log.warn("当前时段已预约,请勿重复预约!examSiteId:{} timePeriodId:{}", examSiteId, timePeriodId);
                         throw new StatusException("当前时段已预约,请勿重复预约");
                     }
 
-                    // 存在“已取消”预约记录,则恢复预约
+                    // 存在历史“已取消”预约记录,则恢复预约
                     existApply.setCancel(false);
                     existApply.setOperateId(student.getId());
                     existApply.setOperateTime(System.currentTimeMillis());
@@ -201,8 +198,8 @@ public class ExamReserveServiceImpl implements ExamReserveService {
                     throw e;
                 }
 
-                // 异常时,释放1个被占数量
-                applyTaskCacheService.decreaseApplyFinishCount(examSiteId, timePeriodId);
+                // 其它异常时,归还1个被占数量
+                applyTaskCacheService.increaseApplyAvailableCount(examSiteId, timePeriodId);
                 log.error("预约异常!examSiteId:{} timePeriodId:{} err:{}", examSiteId, timePeriodId, e.getMessage());
                 throw new StatusException("预约失败,请稍后再试!", e);
             }
@@ -292,8 +289,8 @@ public class ExamReserveServiceImpl implements ExamReserveService {
 
             // this.updateStudentApplyForCancel(existApply.getId(), true, student.getId());
 
-            // 某考点某时段的“已预约数量” 累减1
-            applyTaskCacheService.decreaseApplyFinishCount(examSiteId, timePeriodId);
+            // 某考点某时段的“剩余可约数量” 累加1(归还1个被占数量)
+            applyTaskCacheService.increaseApplyAvailableCount(examSiteId, timePeriodId);
             log.warn("取消预约成功!studentId:{} examSiteId:{} timePeriodId:{}", student.getId(), examSiteId, timePeriodId);
         } finally {
             try {