浏览代码

断点续考交卷如果被锁,则延迟交卷

lideyin 5 年之前
父节点
当前提交
d928d16a99

+ 35 - 7
examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/impl/ExamControlServiceImpl.java

@@ -39,6 +39,7 @@ import cn.com.qmth.examcloud.support.cache.bean.ExtractConfigDetailCacheBean;
 import cn.com.qmth.examcloud.support.cache.bean.ExtractConfigPaperCacheBean;
 import cn.com.qmth.examcloud.support.cache.bean.SysPropertyCacheBean;
 import cn.com.qmth.examcloud.web.bootstrap.PropertyHolder;
+import cn.com.qmth.examcloud.web.exception.SequenceLockException;
 import cn.com.qmth.examcloud.web.helpers.GlobalHelper;
 import cn.com.qmth.examcloud.web.helpers.SequenceLockHelper;
 import cn.com.qmth.examcloud.web.redis.RedisClient;
@@ -64,7 +65,6 @@ import java.net.URLEncoder;
 import java.text.SimpleDateFormat;
 import java.util.*;
 import java.util.concurrent.TimeUnit;
-import java.util.concurrent.locks.LockSupport;
 import java.util.stream.Collectors;
 
 /**
@@ -258,7 +258,7 @@ public class ExamControlServiceImpl implements ExamControlService {
 
         // 更新考生信息
         startTime = System.currentTimeMillis();
-        examStudentEntity=examStudentService.updateExamStudentByStartExam(examStudentEntity, examBean);
+        examStudentEntity = examStudentService.updateExamStudentByStartExam(examStudentEntity, examBean);
         if (log.isDebugEnabled()) {
             log.debug("7 更新考生信息耗时:" + (System.currentTimeMillis() - startTime) + " ms");
         }
@@ -734,7 +734,7 @@ public class ExamControlServiceImpl implements ExamControlService {
 
         startTime = System.currentTimeMillis();
         // 计算保存考试分数
-        examScoreService.saveExamScore(examRecord,examRecordData);
+        examScoreService.saveExamScore(examRecord, examRecordData);
         if (log.isDebugEnabled()) {
             log.debug("3 [HAND_IN_EXAM]计算保存考试分数耗时:" + (System.currentTimeMillis() - startTime) + " ms");
         }
@@ -854,7 +854,7 @@ public class ExamControlServiceImpl implements ExamControlService {
         // 更新心跳次数
         examSessionInfo.setHeartbeat(examSessionInfo.getHeartbeat() + 1);
         // 会话过期时间:秒
-        int expireTime = (examSessionInfo.getExamReconnectTime()  + 1) * 60;
+        int expireTime = (examSessionInfo.getExamReconnectTime() + 1) * 60;
         // 更新考试会话过期时间
         examSessionInfoService.saveExamSessionInfo(studentId, examSessionInfo, expireTime);
         // 返回考试剩余时间 :考试时长-心跳次数*60000
@@ -915,7 +915,7 @@ public class ExamControlServiceImpl implements ExamControlService {
             // 查询考试记录
             ExamRecordDataEntity examRecordData = GlobalHelper.getEntity(examRecordDataRepo, examingRecord.getExamRecordDataId(),
                     ExamRecordDataEntity.class);
-            handInExam(examRecordData, HandInExamType.AUTO);
+            delayHandInExamIfLocked(examRecordData);
             return null;
         }
         // 如果已经过了断点续考时间,清除考试记录,清除会话
@@ -929,11 +929,38 @@ public class ExamControlServiceImpl implements ExamControlService {
             ExamRecordDataEntity examRecordDataEntity = GlobalHelper.getEntity(examRecordDataRepo,
                     examingRecord.getExamRecordDataId(), ExamRecordDataEntity.class);
             handInExam(examRecordDataEntity, HandInExamType.AUTO);
+            delayHandInExamIfLocked(examRecordDataEntity);
             return null;
         }
         return examingRecord;
     }
 
+    /**
+     *  如果有序列化锁,则延迟交卷
+     * @param examRecordData
+     * @return
+     */
+    private void delayHandInExamIfLocked(ExamRecordDataEntity examRecordData) {
+        try {
+            handInExam(examRecordData, HandInExamType.AUTO);
+        } catch (SequenceLockException e) {
+            //如果发现自动服务正在交卷,则重试1500毫秒获取考试记录状态,判断是否已交卷
+            int loopTimes = 0;
+            while (loopTimes <= 15) {
+                loopTimes++;
+                examRecordData = GlobalHelper.getEntity(examRecordDataRepo, examRecordData.getId(),
+                        ExamRecordDataEntity.class);
+
+                //1500毫秒内如果交卷成功,则退出循环
+                if (examRecordData.getExamRecordStatus() != ExamRecordStatus.EXAM_ING) {
+                    return;
+                }
+                Util.sleep(TimeUnit.MILLISECONDS, 100);
+            }
+            throw e;
+        }
+    }
+
     @Override
     public void cleanExamingRecord(ExamingRecordEntity examingRecord) {
 
@@ -1358,7 +1385,7 @@ public class ExamControlServiceImpl implements ExamControlService {
 
         res.setQuestionOrder(eqe.getOrder());
         res.setQuestionMainNumber(eqe.getMainNumber());
-        res.setSubNumber(getSubNumber(examRecordQuestionsEntity,Integer.valueOf(order)));
+        res.setSubNumber(getSubNumber(examRecordQuestionsEntity, Integer.valueOf(order)));
         try {
             this.sendScanQrCodeToWebSocket(clientId, Long.valueOf(examRecordDataId), Integer.valueOf(order));
         } catch (Exception e) {
@@ -1367,7 +1394,7 @@ public class ExamControlServiceImpl implements ExamControlService {
         return res;
     }
 
-    private Integer getSubNumber(ExamRecordQuestionsEntity examRecordQuestionsEntity,Integer order) {
+    private Integer getSubNumber(ExamRecordQuestionsEntity examRecordQuestionsEntity, Integer order) {
         List<UploadedFileAnswerInfo> list = getReSortedQuestionList(examRecordQuestionsEntity);
         for (UploadedFileAnswerInfo info : list) {
             if (order.intValue() == info.getOrder().intValue()) {
@@ -1504,6 +1531,7 @@ public class ExamControlServiceImpl implements ExamControlService {
 
     /**
      * 根据考试记录id获取所有已经重排序号的考试列表
+     *
      * @param examRecordQuestionsEntity
      * @return
      */