浏览代码

断点逻辑修改,加入examStatus锁,加入全局异常错误信息表

wangliang 4 年之前
父节点
当前提交
ad5a550b77

+ 2 - 0
themis-business/src/main/java/com/qmth/themis/business/constant/SystemConstant.java

@@ -125,6 +125,8 @@ public class SystemConstant {
 
     public static final int MAX_EXPORT_SIZE = 500;
 
+    public static final int MAX_EXAM_STATUS_COUNT = 20;
+
     public static final String EXCEL_PREFIX = ".xlsx";
 
     public static final String TXT_PREFIX = ".txt";

+ 1 - 2
themis-business/src/main/java/com/qmth/themis/business/service/TOeExamRecordService.java

@@ -408,9 +408,8 @@ public interface TOeExamRecordService extends IService<TOeExamRecord> {
      * 设置断点信息
      *
      * @param recordId
-     * @param count
      */
-    Boolean setExamBreak(Long recordId, Integer count);
+    Boolean setExamBreak(Long recordId);
 
     /**
      * 发送断点信息

+ 119 - 68
themis-business/src/main/java/com/qmth/themis/business/service/impl/TEExamServiceImpl.java

@@ -20,10 +20,7 @@ import com.qmth.themis.business.dto.cache.TEStudentCacheDto;
 import com.qmth.themis.business.dto.response.TEExamActivityDto;
 import com.qmth.themis.business.dto.response.TEExamDto;
 import com.qmth.themis.business.dto.response.TEExamQueryDto;
-import com.qmth.themis.business.entity.TBSession;
-import com.qmth.themis.business.entity.TBTaskHistory;
-import com.qmth.themis.business.entity.TEExam;
-import com.qmth.themis.business.entity.TOeExamRecord;
+import com.qmth.themis.business.entity.*;
 import com.qmth.themis.business.enums.*;
 import com.qmth.themis.business.service.*;
 import com.qmth.themis.business.util.*;
@@ -103,6 +100,9 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
     @Resource
     MqUtil mqUtil;
 
+    @Resource
+    TGErrorService tgErrorService;
+
     /**
      * 查询考试批次
      *
@@ -511,30 +511,47 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
         ret.setPaperDecryptSecret(ep.getDecryptSecret());
         ret.setPaperDecryptVector(ep.getDecryptVector());
 
-        boolean lock = redisUtil.lock(SystemConstant.REDIS_LOCK_EXAM_STATUS_PREFIX + recordId,
-                SystemConstant.REDIS_LOCK_EXAM_STATUS_TIME_OUT);
-        if (lock) {
-            try {
-                // 更新考试记录缓存
-                Long firstStartTime = System.currentTimeMillis();
-                ExamRecordCacheUtil.setFirstStartTime(recordId, firstStartTime, false);
-                ExamRecordCacheUtil.setStatus(recordId, ExamRecordStatusEnum.ANSWERING, false);
-                Long lastStartTime = System.currentTimeMillis();
-                ExamRecordCacheUtil.setLastStartTime(recordId, lastStartTime, false);
-                String[] columns = new String[]{ExamRecordFieldEnum.first_start_time.name(),
-                        ExamRecordFieldEnum.status.name(), ExamRecordFieldEnum.last_start_time.name()};
-                Object[] values = new Object[]{firstStartTime, ExamRecordStatusEnum.ANSWERING, lastStartTime};
-                toeExamRecordService.dataUpdatesMq(recordId, columns, values);
-                //更新场次-考试记录缓存
-                ExamActivityRecordCacheUtil.setExamRecordStatus(activityId, recordId,
-                        new ExamActivityRecordCacheBean(ExamRecordCacheUtil.getExamStudentId(recordId),
-                                ExamRecordCacheUtil.getStatus(recordId)));
-            } finally {
-                if (Objects.nonNull(recordId)) {
-                    redisUtil.releaseLock(SystemConstant.REDIS_LOCK_EXAM_STATUS_PREFIX + recordId);
+        boolean lock = false;
+        for (int i = 0; i < SystemConstant.MAX_EXAM_STATUS_COUNT; i++) {
+            lock = redisUtil.lock(SystemConstant.REDIS_LOCK_EXAM_STATUS_PREFIX + recordId,
+                    SystemConstant.REDIS_LOCK_EXAM_STATUS_TIME_OUT);
+            if (lock) {
+                try {
+                    // 更新考试记录缓存
+                    Long firstStartTime = System.currentTimeMillis();
+                    ExamRecordCacheUtil.setFirstStartTime(recordId, firstStartTime, false);
+                    ExamRecordCacheUtil.setStatus(recordId, ExamRecordStatusEnum.ANSWERING, false);
+                    Long lastStartTime = System.currentTimeMillis();
+                    ExamRecordCacheUtil.setLastStartTime(recordId, lastStartTime, false);
+                    String[] columns = new String[]{ExamRecordFieldEnum.first_start_time.name(),
+                            ExamRecordFieldEnum.status.name(), ExamRecordFieldEnum.last_start_time.name()};
+                    Object[] values = new Object[]{firstStartTime, ExamRecordStatusEnum.ANSWERING, lastStartTime};
+                    toeExamRecordService.dataUpdatesMq(recordId, columns, values);
+                    //更新场次-考试记录缓存
+                    ExamActivityRecordCacheUtil.setExamRecordStatus(activityId, recordId,
+                            new ExamActivityRecordCacheBean(ExamRecordCacheUtil.getExamStudentId(recordId),
+                                    ExamRecordCacheUtil.getStatus(recordId)));
+                    break;
+                } finally {
+                    if (Objects.nonNull(recordId)) {
+                        redisUtil.releaseLock(SystemConstant.REDIS_LOCK_EXAM_STATUS_PREFIX + recordId);
+                    }
+                }
+            } else {
+                try {
+                    Thread.sleep(500);
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
                 }
             }
-        } else {
+        }
+        if (!lock) {
+            JSONObject jsonObject = new JSONObject();
+            jsonObject.put("recordId", recordId);
+            jsonObject.put("method", "start");
+            jsonObject.put("examStatus", ExamRecordCacheUtil.getStatus(recordId));
+            TGError tgError = new TGError(jsonObject.toJSONString(), System.currentTimeMillis());
+            tgErrorService.save(tgError);
             throw new BusinessException(ExceptionResultEnum.EXAM_STATUS_UPDATE_ERROR);
         }
 
@@ -867,27 +884,44 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
             ret.setAudioLeftPlayCount(audioLeftPlayCounts);
         }
 
-        boolean lock = redisUtil.lock(SystemConstant.REDIS_LOCK_EXAM_STATUS_PREFIX + recordId,
-                SystemConstant.REDIS_LOCK_EXAM_STATUS_TIME_OUT);
-        if (lock) {
-            try {
-                Long lastPrepareTime = System.currentTimeMillis();
-                ExamRecordCacheUtil.setLastPrepareTime(recordId, lastPrepareTime, false);
-                ExamRecordCacheUtil.setStatus(recordId, ExamRecordStatusEnum.RESUME_PREPARE, false);
-                String[] columns = new String[]{ExamRecordFieldEnum.last_prepare_time.name(),
-                        ExamRecordFieldEnum.status.name()};
-                Object[] values = new Object[]{lastPrepareTime, ExamRecordStatusEnum.RESUME_PREPARE};
-                toeExamRecordService.dataUpdatesMq(recordId, columns, values);
-                //更新场次-考试记录缓存
-                ExamActivityRecordCacheUtil.setExamRecordStatus(es.getExamActivityId(), recordId,
-                        new ExamActivityRecordCacheBean(ExamRecordCacheUtil.getExamStudentId(recordId),
-                                ExamRecordCacheUtil.getStatus(recordId)));
-            } finally {
-                if (Objects.nonNull(recordId)) {
-                    redisUtil.releaseLock(SystemConstant.REDIS_LOCK_EXAM_STATUS_PREFIX + recordId);
+        boolean lock = false;
+        for (int i = 0; i < SystemConstant.MAX_EXAM_STATUS_COUNT; i++) {
+            lock = redisUtil.lock(SystemConstant.REDIS_LOCK_EXAM_STATUS_PREFIX + recordId,
+                    SystemConstant.REDIS_LOCK_EXAM_STATUS_TIME_OUT);
+            if (lock) {
+                try {
+                    Long lastPrepareTime = System.currentTimeMillis();
+                    ExamRecordCacheUtil.setLastPrepareTime(recordId, lastPrepareTime, false);
+                    ExamRecordCacheUtil.setStatus(recordId, ExamRecordStatusEnum.RESUME_PREPARE, false);
+                    String[] columns = new String[]{ExamRecordFieldEnum.last_prepare_time.name(),
+                            ExamRecordFieldEnum.status.name()};
+                    Object[] values = new Object[]{lastPrepareTime, ExamRecordStatusEnum.RESUME_PREPARE};
+                    toeExamRecordService.dataUpdatesMq(recordId, columns, values);
+                    //更新场次-考试记录缓存
+                    ExamActivityRecordCacheUtil.setExamRecordStatus(es.getExamActivityId(), recordId,
+                            new ExamActivityRecordCacheBean(ExamRecordCacheUtil.getExamStudentId(recordId),
+                                    ExamRecordCacheUtil.getStatus(recordId)));
+                    break;
+                } finally {
+                    if (Objects.nonNull(recordId)) {
+                        redisUtil.releaseLock(SystemConstant.REDIS_LOCK_EXAM_STATUS_PREFIX + recordId);
+                    }
+                }
+            } else {
+                try {
+                    Thread.sleep(500);
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
                 }
             }
-        } else {
+        }
+        if (!lock) {
+            JSONObject jsonObject = new JSONObject();
+            jsonObject.put("recordId", recordId);
+            jsonObject.put("method", "resume");
+            jsonObject.put("examStatus", ExamRecordCacheUtil.getStatus(recordId));
+            TGError tgError = new TGError(jsonObject.toJSONString(), System.currentTimeMillis());
+            tgErrorService.save(tgError);
             throw new BusinessException(ExceptionResultEnum.EXAM_STATUS_UPDATE_ERROR);
         }
         return ret;
@@ -1029,31 +1063,48 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
         } else {
             ret.setStatus(FinishExamResultEnum.NORMAL);
         }
-        boolean lock = redisUtil.lock(SystemConstant.REDIS_LOCK_EXAM_STATUS_PREFIX + recordId,
-                SystemConstant.REDIS_LOCK_EXAM_STATUS_TIME_OUT);
-        if (lock) {
-            try {
-                Long finishTime = System.currentTimeMillis();
-                ExamRecordCacheUtil.setFinishTime(recordId, finishTime, false);
-                ExamRecordCacheUtil.setDurationSeconds(recordId, durationSeconds, false);
-                ExamRecordCacheUtil.setFinishType(recordId, FinishTypeEnum.valueOf(type), false);
-                ExamRecordCacheUtil.setStatus(recordId, ExamRecordStatusEnum.FINISHED, false);
-                String[] columns = new String[]{ExamRecordFieldEnum.finish_time.name(),
-                        ExamRecordFieldEnum.duration_seconds.name(), ExamRecordFieldEnum.finish_type.name(),
-                        ExamRecordFieldEnum.status.name()};
-                Object[] values = new Object[]{finishTime, durationSeconds, FinishTypeEnum.valueOf(type),
-                        ExamRecordStatusEnum.FINISHED};
-                toeExamRecordService.dataUpdatesMq(recordId, columns, values);
-                //更新场次-考试记录缓存
-                ExamActivityRecordCacheUtil.setExamRecordStatus(es.getExamActivityId(), recordId,
-                        new ExamActivityRecordCacheBean(ExamRecordCacheUtil.getExamStudentId(recordId),
-                                ExamRecordCacheUtil.getStatus(recordId)));
-            } finally {
-                if (Objects.nonNull(recordId)) {
-                    redisUtil.releaseLock(SystemConstant.REDIS_LOCK_EXAM_STATUS_PREFIX + recordId);
+        boolean lock = false;
+        for (int i = 0; i < SystemConstant.MAX_EXAM_STATUS_COUNT; i++) {
+            lock = redisUtil.lock(SystemConstant.REDIS_LOCK_EXAM_STATUS_PREFIX + recordId,
+                    SystemConstant.REDIS_LOCK_EXAM_STATUS_TIME_OUT);
+            if (lock) {
+                try {
+                    Long finishTime = System.currentTimeMillis();
+                    ExamRecordCacheUtil.setFinishTime(recordId, finishTime, false);
+                    ExamRecordCacheUtil.setDurationSeconds(recordId, durationSeconds, false);
+                    ExamRecordCacheUtil.setFinishType(recordId, FinishTypeEnum.valueOf(type), false);
+                    ExamRecordCacheUtil.setStatus(recordId, ExamRecordStatusEnum.FINISHED, false);
+                    String[] columns = new String[]{ExamRecordFieldEnum.finish_time.name(),
+                            ExamRecordFieldEnum.duration_seconds.name(), ExamRecordFieldEnum.finish_type.name(),
+                            ExamRecordFieldEnum.status.name()};
+                    Object[] values = new Object[]{finishTime, durationSeconds, FinishTypeEnum.valueOf(type),
+                            ExamRecordStatusEnum.FINISHED};
+                    toeExamRecordService.dataUpdatesMq(recordId, columns, values);
+                    //更新场次-考试记录缓存
+                    ExamActivityRecordCacheUtil.setExamRecordStatus(es.getExamActivityId(), recordId,
+                            new ExamActivityRecordCacheBean(ExamRecordCacheUtil.getExamStudentId(recordId),
+                                    ExamRecordCacheUtil.getStatus(recordId)));
+                    break;
+                } finally {
+                    if (Objects.nonNull(recordId)) {
+                        redisUtil.releaseLock(SystemConstant.REDIS_LOCK_EXAM_STATUS_PREFIX + recordId);
+                    }
+                }
+            } else {
+                try {
+                    Thread.sleep(500);
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
                 }
             }
-        } else {
+        }
+        if (!lock) {
+            JSONObject jsonObject = new JSONObject();
+            jsonObject.put("recordId", recordId);
+            jsonObject.put("method", "diposeFinish");
+            jsonObject.put("examStatus", ExamRecordCacheUtil.getStatus(recordId));
+            TGError tgError = new TGError(jsonObject.toJSONString(), System.currentTimeMillis());
+            tgErrorService.save(tgError);
             throw new BusinessException(ExceptionResultEnum.EXAM_STATUS_UPDATE_ERROR);
         }
         //更新未完成考试记录id

+ 101 - 102
themis-business/src/main/java/com/qmth/themis/business/service/impl/TOeExamRecordServiceImpl.java

@@ -1016,121 +1016,120 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
      * 设置断点信息
      *
      * @param recordId
-     * @param count
      */
     @Override
     @Transactional
-    public Boolean setExamBreak(Long recordId, Integer count) {
-        boolean lock = redisUtil.lock(SystemConstant.REDIS_LOCK_EXAM_STATUS_PREFIX + recordId,
-                SystemConstant.REDIS_LOCK_EXAM_STATUS_TIME_OUT);
-        if (lock) {
-            try {
-                Integer alreadyBreakCount = Objects.isNull(ExamRecordCacheUtil.getAlreadyBreakCount(recordId)) ?
-                        0 :
-                        ExamRecordCacheUtil.getAlreadyBreakCount(recordId);
-                alreadyBreakCount++;
-                Long examActivityId = ExamRecordCacheUtil.getExamActivityId(recordId);
-                Long breakId = uidUtil.getId();
-                ExamRecordCacheUtil.setLastBreakId(recordId, breakId, false);
-                ExamRecordCacheUtil.setStatus(recordId, ExamRecordStatusEnum.BREAK_OFF, false);
-                Long lastBreakTimeNow = System.currentTimeMillis();
-                ExamRecordCacheUtil.setLastBreakTime(recordId, lastBreakTimeNow, false);
-                ExamRecordCacheUtil.setAlreadyBreakCount(recordId, alreadyBreakCount, false);
-                Long lastStartTime = System.currentTimeMillis();
-                ExamRecordCacheUtil.setLastStartTime(recordId, lastStartTime, false);
-                String[] columns = new String[]{ExamRecordFieldEnum.last_break_id.name(),
-                        ExamRecordFieldEnum.status.name(), ExamRecordFieldEnum.last_break_time.name(),
-                        ExamRecordFieldEnum.already_break_count.name(), ExamRecordFieldEnum.last_start_time.name()};
-                Object[] values = new Object[]{breakId, ExamRecordStatusEnum.BREAK_OFF, lastBreakTimeNow,
-                        alreadyBreakCount, lastStartTime};
-                TOeExamRecordService tOeExamRecordService = SpringContextHolder.getBean(TOeExamRecordService.class);
-                tOeExamRecordService.dataUpdatesMq(recordId, columns, values);
-                //考试断点异常原因 发送mq start
-                MqDto mqDtoBreak = new MqDto(mqUtil.getMqGroupDomain().getTopic(), MqTagEnum.EXAM_BREAK.name(),
-                        ExceptionEnum.NET_TIME_OUT, MqTagEnum.EXAM_BREAK, String.valueOf(recordId),
-                        String.valueOf(recordId));
-                MqDtoService mqDtoService = SpringContextHolder.getBean(MqDtoService.class);
-                mqDtoService.assembleSendOneWayMsg(mqDtoBreak);
-                //考试断点异常原因 发送mq end
-
-                Long examId = ExamRecordCacheUtil.getExamId(recordId);
-                ExamCacheBean ec = examService.getExamCacheBean(examId);//考试缓存
-                Integer breakExpireSeconds = Objects.isNull(ec.getBreakExpireSeconds()) ?
-                        0 :
-                        ec.getBreakExpireSeconds();
-                if (breakExpireSeconds.intValue() > 0) {
-                    List<String> list = SystemConstant.mqDelayLevelList.subList(5, 15);
-                    String level = null;
-                    if (breakExpireSeconds.intValue() <= 60) {
-                        level = "1m";
-                    } else {
-                        Integer time = breakExpireSeconds.intValue() / 60;
-                        if (time.intValue() >= 30) {
-                            level = "30m";
+    public Boolean setExamBreak(Long recordId) {
+        boolean lock = false;
+        for (int i = 0; i < SystemConstant.MAX_EXAM_STATUS_COUNT; i++) {
+            lock = redisUtil.lock(SystemConstant.REDIS_LOCK_EXAM_STATUS_PREFIX + recordId,
+                    SystemConstant.REDIS_LOCK_EXAM_STATUS_TIME_OUT);
+            if (lock) {
+                try {
+                    Integer alreadyBreakCount = Objects.isNull(ExamRecordCacheUtil.getAlreadyBreakCount(recordId)) ?
+                            0 :
+                            ExamRecordCacheUtil.getAlreadyBreakCount(recordId);
+                    alreadyBreakCount++;
+                    Long examActivityId = ExamRecordCacheUtil.getExamActivityId(recordId);
+                    Long breakId = uidUtil.getId();
+                    ExamRecordCacheUtil.setLastBreakId(recordId, breakId, false);
+                    ExamRecordCacheUtil.setStatus(recordId, ExamRecordStatusEnum.BREAK_OFF, false);
+                    Long lastBreakTimeNow = System.currentTimeMillis();
+                    ExamRecordCacheUtil.setLastBreakTime(recordId, lastBreakTimeNow, false);
+                    ExamRecordCacheUtil.setAlreadyBreakCount(recordId, alreadyBreakCount, false);
+                    Long lastStartTime = System.currentTimeMillis();
+                    ExamRecordCacheUtil.setLastStartTime(recordId, lastStartTime, false);
+                    String[] columns = new String[]{ExamRecordFieldEnum.last_break_id.name(),
+                            ExamRecordFieldEnum.status.name(), ExamRecordFieldEnum.last_break_time.name(),
+                            ExamRecordFieldEnum.already_break_count.name(), ExamRecordFieldEnum.last_start_time.name()};
+                    Object[] values = new Object[]{breakId, ExamRecordStatusEnum.BREAK_OFF, lastBreakTimeNow,
+                            alreadyBreakCount, lastStartTime};
+                    TOeExamRecordService tOeExamRecordService = SpringContextHolder.getBean(TOeExamRecordService.class);
+                    tOeExamRecordService.dataUpdatesMq(recordId, columns, values);
+                    //考试断点异常原因 发送mq start
+                    MqDto mqDtoBreak = new MqDto(mqUtil.getMqGroupDomain().getTopic(), MqTagEnum.EXAM_BREAK.name(),
+                            ExceptionEnum.NET_TIME_OUT, MqTagEnum.EXAM_BREAK, String.valueOf(recordId),
+                            String.valueOf(recordId));
+                    MqDtoService mqDtoService = SpringContextHolder.getBean(MqDtoService.class);
+                    mqDtoService.assembleSendOneWayMsg(mqDtoBreak);
+                    //考试断点异常原因 发送mq end
+
+                    Long examId = ExamRecordCacheUtil.getExamId(recordId);
+                    ExamCacheBean ec = examService.getExamCacheBean(examId);//考试缓存
+                    Integer breakExpireSeconds = Objects.isNull(ec.getBreakExpireSeconds()) ?
+                            0 :
+                            ec.getBreakExpireSeconds();
+                    if (breakExpireSeconds.intValue() > 0) {
+                        List<String> list = SystemConstant.mqDelayLevelList.subList(5, 15);
+                        String level = null;
+                        if (breakExpireSeconds.intValue() <= 60) {
+                            level = "1m";
                         } else {
-                            for (String s : list) {
-                                Integer value = Integer.parseInt(s.substring(0, s.length() - 1));
-                                if (time.intValue() <= value.intValue()) {
-                                    level = value + "m";
-                                    break;
+                            Integer time = breakExpireSeconds.intValue() / 60;
+                            if (time.intValue() >= 30) {
+                                level = "30m";
+                            } else {
+                                for (String s : list) {
+                                    Integer value = Integer.parseInt(s.substring(0, s.length() - 1));
+                                    if (time.intValue() <= value.intValue()) {
+                                        level = value + "m";
+                                        break;
+                                    }
                                 }
                             }
                         }
+                        Map<String, Object> tranMap = new HashMap<>();
+                        Integer time = SystemConstant.mqDelayLevel.get(level);
+                        LocalDateTime dt = LocalDateTime.now();
+                        if (level.contains("m")) {
+                            dt = dt.plusMinutes(Long.parseLong(level.replace("m", "")));
+                        } else {
+                            dt = dt.plusSeconds(Long.parseLong(level.replace("s", "")));
+                        }
+                        tranMap.put("recordId", recordId);
+                        tranMap.put("timeOut", time);
+                        tranMap.put("mqExecTime", dt.toInstant(ZoneOffset.of("+8")).toEpochMilli());
+                        //考试断点延时消息 发送mq start
+                        MqDto mqDtoBreakDelay = new MqDto(mqUtil.getMqGroupDomain().getTopic(),
+                                MqTagEnum.EXAM_BREAK_DELAY.name(), MqTagEnum.EXAM_BREAK_DELAY, MqTagEnum.EXAM_BREAK_DELAY,
+                                String.valueOf(recordId), tranMap, String.valueOf(recordId));
+                        mqDtoService.assembleSendAsyncDelayMsg(mqDtoBreakDelay);
+                        //考试断点延时消息 发送mq end
                     }
-                    Map<String, Object> tranMap = new HashMap<>();
-                    Integer time = SystemConstant.mqDelayLevel.get(level);
-                    LocalDateTime dt = LocalDateTime.now();
-                    if (level.contains("m")) {
-                        dt = dt.plusMinutes(Long.parseLong(level.replace("m", "")));
+                    //更新场次-考试记录缓存
+                    ExamActivityRecordCacheUtil.setExamRecordStatus(examActivityId, recordId,
+                            new ExamActivityRecordCacheBean(ExamRecordCacheUtil.getExamStudentId(recordId),
+                                    ExamRecordCacheUtil.getStatus(recordId)));
+                    break;
+                } catch (Exception e) {
+                    log.error("请求出错", e);
+                    if (e instanceof BusinessException) {
+                        throw new BusinessException(e.getMessage());
                     } else {
-                        dt = dt.plusSeconds(Long.parseLong(level.replace("s", "")));
+                        throw new RuntimeException(e);
+                    }
+                } finally {
+                    if (Objects.nonNull(recordId)) {
+                        redisUtil.releaseLock(SystemConstant.REDIS_LOCK_EXAM_STATUS_PREFIX + recordId);
                     }
-                    tranMap.put("recordId", recordId);
-                    tranMap.put("timeOut", time);
-                    tranMap.put("mqExecTime", dt.toInstant(ZoneOffset.of("+8")).toEpochMilli());
-                    //考试断点延时消息 发送mq start
-                    MqDto mqDtoBreakDelay = new MqDto(mqUtil.getMqGroupDomain().getTopic(),
-                            MqTagEnum.EXAM_BREAK_DELAY.name(), MqTagEnum.EXAM_BREAK_DELAY, MqTagEnum.EXAM_BREAK_DELAY,
-                            String.valueOf(recordId), tranMap, String.valueOf(recordId));
-                    mqDtoService.assembleSendAsyncDelayMsg(mqDtoBreakDelay);
-                    //考试断点延时消息 发送mq end
-                }
-                //更新场次-考试记录缓存
-                ExamActivityRecordCacheUtil.setExamRecordStatus(examActivityId, recordId,
-                        new ExamActivityRecordCacheBean(ExamRecordCacheUtil.getExamStudentId(recordId),
-                                ExamRecordCacheUtil.getStatus(recordId)));
-            } catch (Exception e) {
-                log.error("请求出错", e);
-                if (e instanceof BusinessException) {
-                    throw new BusinessException(e.getMessage());
-                } else {
-                    throw new RuntimeException(e);
-                }
-            } finally {
-                if (Objects.nonNull(recordId)) {
-                    redisUtil.releaseLock(SystemConstant.REDIS_LOCK_EXAM_STATUS_PREFIX + recordId);
                 }
-            }
-        } else {
-            try {
-                Thread.sleep(500);
-            } catch (InterruptedException e) {
-                e.printStackTrace();
-            }
-            if (count >= 20) {
-                JSONObject jsonObject = new JSONObject();
-                jsonObject.put("recordId", recordId);
-                jsonObject.put("method", "setExamBreak");
-                jsonObject.put("examStatus", ExamRecordCacheUtil.getStatus(recordId));
-                TGError tgError = new TGError(jsonObject.toJSONString(), System.currentTimeMillis());
-                tgErrorService.save(tgError);
-                return false;
             } else {
-                count++;
-                setExamBreak(recordId, count);
+                try {
+                    Thread.sleep(500);
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
+                }
             }
         }
-        return true;
+        if (!lock) {
+            JSONObject jsonObject = new JSONObject();
+            jsonObject.put("recordId", recordId);
+            jsonObject.put("method", "setExamBreak");
+            jsonObject.put("examStatus", ExamRecordCacheUtil.getStatus(recordId));
+            TGError tgError = new TGError(jsonObject.toJSONString(), System.currentTimeMillis());
+            tgErrorService.save(tgError);
+        }
+        return lock;
     }
 
     /**
@@ -1144,7 +1143,7 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
         Boolean finished = false;
         try {
             if (setBreak) {
-                this.setExamBreak(recordId, 0);
+                this.setExamBreak(recordId);
             }
             Long examId = ExamRecordCacheUtil.getExamId(recordId);
             Long examStudentId = ExamRecordCacheUtil.getExamStudentId(recordId);

+ 1 - 1
themis-exam/src/main/java/com/qmth/themis/exam/api/TEStudentController.java

@@ -266,7 +266,7 @@ public class TEStudentController {
                 //只有ANSWERING状态才生成断点
                 if (Objects.equals(status, ExamRecordStatusEnum.ANSWERING)) {
                     ExamConstant.sendExamStopMsg(recordId, true);
-                    tOeExamRecordService.setExamBreak(recordId, 0);
+                    tOeExamRecordService.setExamBreak(recordId);
                 }
                 Boolean finished = tOeExamRecordService.sendExamBreakMsg(recordId, false);
                 if (finished) {