haogh 1 рік тому
батько
коміт
853c44a7d0

+ 44 - 19
src/main/java/com/qmth/exam/reserve/service/impl/StudentApplyServiceImpl.java

@@ -15,11 +15,11 @@ import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.concurrent.locks.Lock;
 import java.util.stream.Collectors;
 
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.time.DateUtils;
+import org.redisson.api.RLock;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -150,16 +150,14 @@ public class StudentApplyServiceImpl extends ServiceImpl<StudentApplyDao, Studen
         }
 
         String studentApplyLockKey = String.format(CacheConstants.LOCK_STUDENT_APPLY, studentApply.getStudentId());
-        Lock studentApplyLock = concurrentService.getLock(studentApplyLockKey);
+        RLock studentApplyLock = (RLock) concurrentService.getLock(studentApplyLockKey);
         try {
             if (!studentApplyLock.tryLock()) {
                 log.warn("获取锁失败,同一个考生不允许同时操作预约!lockKey:{}", studentApplyLockKey);
                 throw new StatusException(Constants.SYSTEM_BUSY);
-            }
-
-            log.warn("获取锁成功!lockKey:{}", studentApplyLockKey);
+            } else {
+                log.warn("获取锁成功!lockKey:{}", studentApplyLockKey);
 
-            if (studentApplyLock.tryLock()) {
                 studentApply.setCancel(Boolean.TRUE);
                 this.baseMapper.updateById(studentApply);
 
@@ -180,7 +178,11 @@ public class StudentApplyServiceImpl extends ServiceImpl<StudentApplyDao, Studen
             throw new StatusException("取消预约失败,请稍后再试!", e);
         } finally {
             try {
-                studentApplyLock.unlock();
+                // 解锁前检查当前线程是否持有该锁
+                if (studentApplyLock.isLocked() && studentApplyLock.isHeldByCurrentThread()) {
+                    studentApplyLock.unlock();
+                    log.info("解锁成功!lockKey:{}", studentApplyLockKey);
+                }
             } catch (Exception e) {
                 log.warn(e.getMessage());
             }
@@ -406,9 +408,7 @@ public class StudentApplyServiceImpl extends ServiceImpl<StudentApplyDao, Studen
             if (studentApplyFinishCount > 0 && studentApplyFinishCount < vo.getApplyNumber()) {
                 List<AgentAndTimeVO> availableList = listAvailableTime(haveApplyList, agentTimeList);
                 // 需要填充的次数
-                for (int j = 0; j < availableList.size(); j++) {
-                    tobeInsertTimeList.add(availableList.get(j));
-                }
+                tobeInsertTimeList.addAll(availableList);
             }
 
             // 未预约
@@ -475,7 +475,7 @@ public class StudentApplyServiceImpl extends ServiceImpl<StudentApplyDao, Studen
         List<StudentApplyEntity> ApplyList = new ArrayList<>();
         List<AgentAndTimeVO> agentTimeList = vo.getAgentTimeList();
         String studentApplyLockKey = String.format(CacheConstants.LOCK_STUDENT_APPLY, vo.getStudentId());
-        Lock studentApplyLock = concurrentService.getLock(studentApplyLockKey);
+        RLock studentApplyLock = (RLock) concurrentService.getLock(studentApplyLockKey);
         try {
             if (!studentApplyLock.tryLock()) {
                 log.warn("获取锁失败,考生在同时操作预约!lockKey:{}", studentApplyLockKey);
@@ -526,7 +526,10 @@ public class StudentApplyServiceImpl extends ServiceImpl<StudentApplyDao, Studen
             throw new StatusException("导入预考失败,请稍后再试!", e);
         } finally {
             try {
-                studentApplyLock.unlock();
+                if (studentApplyLock.isLocked() && studentApplyLock.isHeldByCurrentThread()) {
+                    studentApplyLock.unlock();
+                    log.info("解锁成功!lockKey:{}", studentApplyLockKey);
+                }
             } catch (Exception e) {
                 log.warn(e.getMessage());
             }
@@ -606,12 +609,15 @@ public class StudentApplyServiceImpl extends ServiceImpl<StudentApplyDao, Studen
     @Override
     public void autoAssign(Long taskId, Long userId) {
         checkAfterOpenTime();
-        Lock lock = concurrentService.getLock(CacheConstants.LOCK_AUTO_APPLY);
+        RLock lock = (RLock) concurrentService.getLock(CacheConstants.LOCK_AUTO_APPLY);
         try {
             if (!lock.tryLock()) {
                 log.warn("获取锁失败,不允许同时执行自动分配!lockKey:{}", CacheConstants.LOCK_AUTO_APPLY);
                 throw new StatusException("其他老师正在执行自动分配,请不要重复执行!");
             }
+
+            log.warn("获取锁成功!lockKey:{}", CacheConstants.LOCK_AUTO_APPLY);
+
             // 1、未完成预约的考生
             List<StudentEntity> studentList = studentService.listNoFinishStudent(taskId, Boolean.FALSE);
             Map<Long, List<StudentEntity>> noFinishApplyMap = studentList.stream()
@@ -646,7 +652,11 @@ public class StudentApplyServiceImpl extends ServiceImpl<StudentApplyDao, Studen
             throw new StatusException(e.getMessage());
         } finally {
             try {
-                lock.unlock();
+                // 解锁前检查当前线程是否持有该锁
+                if (lock.isLocked() && lock.isHeldByCurrentThread()) {
+                    lock.unlock();
+                    log.info("解锁成功!lockKey:{}", CacheConstants.LOCK_AUTO_APPLY);
+                }
             } catch (Exception e) {
                 log.warn(e.getMessage());
             }
@@ -668,13 +678,13 @@ public class StudentApplyServiceImpl extends ServiceImpl<StudentApplyDao, Studen
         List<StudentApplyEntity> insertApplyList = new ArrayList<>();
         int num = 0;
         String studentApplyLockKey = null;
-        Lock studentApplyLock = null;
+        RLock studentApplyLock = null;
         for (Iterator<StudentEntity> iterator = teachingStudentList.iterator(); iterator.hasNext();) {
             StudentEntity student = iterator.next();
             if (num >= remainNum)
                 break;
             studentApplyLockKey = String.format(CacheConstants.LOCK_STUDENT_APPLY, student.getId());
-            studentApplyLock = concurrentService.getLock(studentApplyLockKey);
+            studentApplyLock = (RLock) concurrentService.getLock(studentApplyLockKey);
             try {
                 if (!studentApplyLock.tryLock()) {
                     log.warn("获取锁失败,考生在同时操作预约!lockKey:{}", studentApplyLockKey);
@@ -728,7 +738,11 @@ public class StudentApplyServiceImpl extends ServiceImpl<StudentApplyDao, Studen
                 throw new StatusException("自动安排预约失败,请稍后再试!");
             } finally {
                 try {
-                    studentApplyLock.unlock();
+                    // 解锁前检查当前线程是否持有该锁
+                    if (studentApplyLock.isLocked() && studentApplyLock.isHeldByCurrentThread()) {
+                        studentApplyLock.unlock();
+                        log.info("解锁成功!lockKey:{}", studentApplyLockKey);
+                    }
                 } catch (Exception e) {
                     log.warn(e.getMessage());
                 }
@@ -849,12 +863,15 @@ public class StudentApplyServiceImpl extends ServiceImpl<StudentApplyDao, Studen
         }
         String autoLayoutLockKey = String.format(CacheConstants.LOCK_ARRANGE_EXAM,
                 DateUtil.formatShortDateString(new Date()));
-        Lock autoLayoutLock = concurrentService.getLock(autoLayoutLockKey);
+        RLock autoLayoutLock = (RLock) concurrentService.getLock(autoLayoutLockKey);
         try {
             if (!autoLayoutLock.tryLock()) {
                 log.warn("获取锁失败,已有线程在执行排考!lockKey:{}", autoLayoutLock);
                 return;
             }
+
+            log.warn("获取锁成功!lockKey:{}", autoLayoutLockKey);
+
             // 1.根据当前日期,查询不能取消的时段
             List<TimePeriodEntity> timePeriodList = listTimePeroid(applyTask.getId());
             List<TimePeriodEntity> noCancelTimePeroidList = listNoCancelApplyTimePeroid(timePeriodList,
@@ -889,7 +906,15 @@ public class StudentApplyServiceImpl extends ServiceImpl<StudentApplyDao, Studen
             log.error(e.getMessage());
             e.printStackTrace();
         } finally {
-            autoLayoutLock.unlock();
+            try {
+                // 解锁前检查当前线程是否持有该锁
+                if (autoLayoutLock.isLocked() && autoLayoutLock.isHeldByCurrentThread()) {
+                    autoLayoutLock.unlock();
+                    log.info("解锁成功!lockKey:{}", autoLayoutLockKey);
+                }
+            } catch (Exception e) {
+                log.warn(e.getMessage());
+            }
         }
     }