浏览代码

face和liveness加锁

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

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

@@ -230,6 +230,21 @@ public class SystemConstant {
     //手机锁
     public static final String REDIS_LOCK_MOBILE_AUTHORIZATION_PREFIX = "lock:mobile:authorization_";
 
+    //人脸检测锁
+    public static final String REDIS_LOCK_FACE_VERIFY_PREFIX = "lock:face:verify_";
+
+    //多张人脸检测锁
+    public static final String REDIS_LOCK_FACE_MULTIPLE_VERIFY_PREFIX = "lock:face:multiple:verify_";
+
+    //人脸比对异常锁
+    public static final String REDIS_LOCK_FACE_COMPARE_VERIFY_PREFIX = "lock:face:compare:verify_";
+
+    //真实性锁
+    public static final String REDIS_LOCK_REALNESS_VERIFY_PREFIX = "lock:realness:verify_";
+
+    //闭眼检测锁
+    public static final String REDIS_LOCK_EYE_CLOSE_VERIFY_PREFIX = "lock:eye_close:verify_";
+
     /**
      * redis过期时间
      */

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

@@ -89,7 +89,7 @@ public class TEFaceController {
         transMap.put("exception", param.getException());
         //mq发送消息start
         MqDto mqDto = new MqDto(mqUtil.getMqGroupDomain().getTopic(), MqTagEnum.FACE_VERIFY_SAVE.name(), transMap, MqTagEnum.FACE_VERIFY_SAVE, param.getRecordId().toString(), param.getRecordId().toString());
-        mqDtoService.assembleSendOneWayMsg(mqDto);
+        mqDtoService.assembleSendOneOrderMsg(mqDto);
         return ResultUtil.ok(ret);
     }
 

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

@@ -88,7 +88,7 @@ public class TELivenessController {
         // mq发送消息start
         MqDto mqDto = new MqDto(mqUtil.getMqGroupDomain().getTopic(), MqTagEnum.LIVENESS_VERIFY_SAVE.name(), transMap,
                 MqTagEnum.LIVENESS_VERIFY_SAVE, param.getRecordId().toString(), param.getRecordId().toString());
-        mqDtoService.assembleSendOneWayMsg(mqDto);
+        mqDtoService.assembleSendOneOrderMsg(mqDto);
         return ResultUtil.ok(ret);
     }
 

+ 311 - 130
themis-mq/src/main/java/com/qmth/themis/mq/service/impl/MqLogicServiceImpl.java

@@ -118,6 +118,9 @@ public class MqLogicServiceImpl implements MqLogicService {
     @Resource
     MqUtil mqUtil;
 
+    @Resource
+    TGErrorService tgErrorService;
+
     /**
      * mq最大重试次数逻辑
      *
@@ -358,23 +361,46 @@ public class MqLogicServiceImpl implements MqLogicService {
             WarningDto warningDto = new WarningDto(warningEnum, faceCount, realness, recordId, photoUrl);
             if (Objects.equals(VerifyExceptionEnum.NONE, warningEnum)) {//无异常,往考生日志表里插一条
                 if (Objects.nonNull(realness) && realness.intValue() == 0) {//真实性异常
-                    String realnessErrorRandom = ExamRecordCacheUtil.getRealnessErrorRandom(recordId);
-                    if (Objects.isNull(realnessErrorRandom)) {
-                        realnessErrorRandom = String.valueOf(UUID.randomUUID()).replaceAll("-", "");
-                        ExamRecordCacheUtil.setRealnessErrorRandom(recordId, realnessErrorRandom);
+                    boolean lock = false;
+                    for (int k = 0; k < SystemConstant.MAX_EXAM_STATUS_COUNT; k++) {
+                        lock = redisUtil.lock(SystemConstant.REDIS_LOCK_REALNESS_VERIFY_PREFIX + recordId,
+                                SystemConstant.REDIS_CACHE_TIME_OUT);
+                        if (lock) {
+                            try {
+                                String realnessErrorRandom = ExamRecordCacheUtil.getRealnessErrorRandom(recordId);
+                                if (Objects.isNull(realnessErrorRandom)) {
+                                    realnessErrorRandom = String.valueOf(UUID.randomUUID()).replaceAll("-", "");
+                                    ExamRecordCacheUtil.setRealnessErrorRandom(recordId, realnessErrorRandom);
+                                }
+                                ExamRecordCacheUtil
+                                        .setRealnessErrorNum(recordId, new AtomicInteger(ExamRecordCacheUtil.getRealnessErrorNum(recordId).incrementAndGet()));
+                                warningDto.setRandom(realnessErrorRandom);
+                                faceVerifyHistoryService
+                                        .save(id, recordId, type, photoUrl, faceCount, similarity, realness, time, exception,
+                                                realnessErrorRandom);
+                                Integer count = ExamRecordCacheUtil.getRealnessErrorNum(recordId).get();
+                                if (count > teConfig.getRealnessCount()) {
+                                    ExamRecordCacheUtil.setRealnessErrorRandom(recordId,
+                                            String.valueOf(UUID.randomUUID()).replaceAll("-", ""));
+                                    ExamRecordCacheUtil.setRealnessErrorNum(recordId, new AtomicInteger(0));
+                                    warningService.realnessError(warningDto);
+                                }
+                                break;
+                            } finally {
+                                if (Objects.nonNull(recordId)) {
+                                    redisUtil.releaseLock(SystemConstant.REDIS_LOCK_REALNESS_VERIFY_PREFIX + recordId);
+                                }
+                            }
+                        } else {
+                            try {
+                                Thread.sleep(500);
+                            } catch (InterruptedException e) {
+                                e.printStackTrace();
+                            }
+                        }
                     }
-                    ExamRecordCacheUtil
-                            .setRealnessErrorNum(recordId, new AtomicInteger(ExamRecordCacheUtil.getRealnessErrorNum(recordId).incrementAndGet()));
-                    warningDto.setRandom(realnessErrorRandom);
-                    faceVerifyHistoryService
-                            .save(id, recordId, type, photoUrl, faceCount, similarity, realness, time, exception,
-                                    realnessErrorRandom);
-                    Integer count = ExamRecordCacheUtil.getRealnessErrorNum(recordId).get();
-                    if (count > teConfig.getRealnessCount()) {
-                        ExamRecordCacheUtil.setRealnessErrorRandom(recordId,
-                                String.valueOf(UUID.randomUUID()).replaceAll("-", ""));
-                        ExamRecordCacheUtil.setRealnessErrorNum(recordId, new AtomicInteger(0));
-                        warningService.realnessError(warningDto);
+                    if (!lock) {
+                        tgErrorService.saveExamTgError(recordId, "faceVerifyRealnessError");
                     }
                 } else {
                     faceVerifyHistoryService
@@ -383,81 +409,173 @@ public class MqLogicServiceImpl implements MqLogicService {
             } else {
                 if (Objects.equals(VerifyExceptionEnum.FACE_COUNT_ERROR, warningEnum)) {//人脸数量异常
                     if (faceCount > 1) {//多张人脸
-                        String multipleFaceRandom = ExamRecordCacheUtil.getMultipleFaceCountErrorRandom(recordId);
-                        if (Objects.isNull(multipleFaceRandom)) {
-                            multipleFaceRandom = String.valueOf(UUID.randomUUID()).replaceAll("-", "");
-                            ExamRecordCacheUtil.setMultipleFaceCountErrorRandom(recordId, multipleFaceRandom);
+                        boolean lock = false;
+                        for (int k = 0; k < SystemConstant.MAX_EXAM_STATUS_COUNT; k++) {
+                            lock = redisUtil.lock(SystemConstant.REDIS_LOCK_FACE_MULTIPLE_VERIFY_PREFIX + recordId,
+                                    SystemConstant.REDIS_CACHE_TIME_OUT);
+                            if (lock) {
+                                try {
+                                    String multipleFaceRandom = ExamRecordCacheUtil.getMultipleFaceCountErrorRandom(recordId);
+                                    if (Objects.isNull(multipleFaceRandom)) {
+                                        multipleFaceRandom = String.valueOf(UUID.randomUUID()).replaceAll("-", "");
+                                        ExamRecordCacheUtil.setMultipleFaceCountErrorRandom(recordId, multipleFaceRandom);
+                                    }
+                                    ExamRecordCacheUtil.setMultipleFaceCountErrorNum(recordId,
+                                            new AtomicInteger(ExamRecordCacheUtil.getMultipleFaceCountErrorNum(recordId).incrementAndGet()));
+                                    warningDto.setRandom(multipleFaceRandom);
+                                    faceVerifyHistoryService
+                                            .save(id, recordId, type, photoUrl, faceCount, similarity, realness, time, exception,
+                                                    multipleFaceRandom);
+                                    Integer count = ExamRecordCacheUtil.getMultipleFaceCountErrorNum(recordId).get();
+                                    if (count > teConfig.getMultipleFaceCountError()) {
+                                        ExamRecordCacheUtil.setMultipleFaceCountErrorRandom(recordId,
+                                                String.valueOf(UUID.randomUUID()).replaceAll("-", ""));
+                                        ExamRecordCacheUtil.setMultipleFaceCountErrorNum(recordId, new AtomicInteger(0));
+                                        warningService.faceCountError(warningDto);
+                                    }
+                                    break;
+                                } finally {
+                                    if (Objects.nonNull(recordId)) {
+                                        redisUtil.releaseLock(SystemConstant.REDIS_LOCK_FACE_MULTIPLE_VERIFY_PREFIX + recordId);
+                                    }
+                                }
+                            } else {
+                                try {
+                                    Thread.sleep(500);
+                                } catch (InterruptedException e) {
+                                    e.printStackTrace();
+                                }
+                            }
                         }
-                        ExamRecordCacheUtil.setMultipleFaceCountErrorNum(recordId,
-                                new AtomicInteger(ExamRecordCacheUtil.getMultipleFaceCountErrorNum(recordId).incrementAndGet()));
-                        warningDto.setRandom(multipleFaceRandom);
-                        faceVerifyHistoryService
-                                .save(id, recordId, type, photoUrl, faceCount, similarity, realness, time, exception,
-                                        multipleFaceRandom);
-                        Integer count = ExamRecordCacheUtil.getMultipleFaceCountErrorNum(recordId).get();
-                        if (count > teConfig.getMultipleFaceCountError()) {
-                            ExamRecordCacheUtil.setMultipleFaceCountErrorRandom(recordId,
-                                    String.valueOf(UUID.randomUUID()).replaceAll("-", ""));
-                            ExamRecordCacheUtil.setMultipleFaceCountErrorNum(recordId, new AtomicInteger(0));
-                            warningService.faceCountError(warningDto);
+                        if (!lock) {
+                            tgErrorService.saveExamTgError(recordId, "faceVerifyMultipleFaceCountError");
                         }
                     } else if (faceCount <= 0) {
-                        String noFaceRandom = ExamRecordCacheUtil.getNoFaceCountErrorRandom(recordId);
-                        if (Objects.isNull(noFaceRandom)) {
-                            noFaceRandom = String.valueOf(UUID.randomUUID()).replaceAll("-", "");
-                            ExamRecordCacheUtil.setNoFaceCountErrorRandom(recordId, noFaceRandom);
+                        boolean lock = false;
+                        for (int k = 0; k < SystemConstant.MAX_EXAM_STATUS_COUNT; k++) {
+                            lock = redisUtil.lock(SystemConstant.REDIS_LOCK_FACE_VERIFY_PREFIX + recordId,
+                                    SystemConstant.REDIS_CACHE_TIME_OUT);
+                            if (lock) {
+                                try {
+                                    String noFaceRandom = ExamRecordCacheUtil.getNoFaceCountErrorRandom(recordId);
+                                    if (Objects.isNull(noFaceRandom)) {
+                                        noFaceRandom = String.valueOf(UUID.randomUUID()).replaceAll("-", "");
+                                        ExamRecordCacheUtil.setNoFaceCountErrorRandom(recordId, noFaceRandom);
+                                    }
+                                    ExamRecordCacheUtil.setNoFaceCountErrorNum(recordId,
+                                            new AtomicInteger(ExamRecordCacheUtil.getNoFaceCountErrorNum(recordId).incrementAndGet()));
+                                    warningDto.setRandom(noFaceRandom);
+                                    faceVerifyHistoryService
+                                            .save(id, recordId, type, photoUrl, faceCount, similarity, realness, time, exception,
+                                                    noFaceRandom);
+                                    Integer count = ExamRecordCacheUtil.getNoFaceCountErrorNum(recordId).get();
+                                    if (count > teConfig.getNoFaceCountError()) {
+                                        ExamRecordCacheUtil.setNoFaceCountErrorRandom(recordId,
+                                                String.valueOf(UUID.randomUUID()).replaceAll("-", ""));
+                                        ExamRecordCacheUtil.setNoFaceCountErrorNum(recordId, new AtomicInteger(0));
+                                        warningService.faceCountError(warningDto);
+                                    }
+                                    break;
+                                } finally {
+                                    if (Objects.nonNull(recordId)) {
+                                        redisUtil.releaseLock(SystemConstant.REDIS_LOCK_FACE_VERIFY_PREFIX + recordId);
+                                    }
+                                }
+                            } else {
+                                try {
+                                    Thread.sleep(500);
+                                } catch (InterruptedException e) {
+                                    e.printStackTrace();
+                                }
+                            }
                         }
-                        ExamRecordCacheUtil.setNoFaceCountErrorNum(recordId,
-                                new AtomicInteger(ExamRecordCacheUtil.getNoFaceCountErrorNum(recordId).incrementAndGet()));
-                        warningDto.setRandom(noFaceRandom);
-                        faceVerifyHistoryService
-                                .save(id, recordId, type, photoUrl, faceCount, similarity, realness, time, exception,
-                                        noFaceRandom);
-                        Integer count = ExamRecordCacheUtil.getNoFaceCountErrorNum(recordId).get();
-                        if (count > teConfig.getNoFaceCountError()) {
-                            ExamRecordCacheUtil.setNoFaceCountErrorRandom(recordId,
-                                    String.valueOf(UUID.randomUUID()).replaceAll("-", ""));
-                            ExamRecordCacheUtil.setNoFaceCountErrorNum(recordId, new AtomicInteger(0));
-                            warningService.faceCountError(warningDto);
+                        if (!lock) {
+                            tgErrorService.saveExamTgError(recordId, "faceVerifyFaceCountError");
                         }
                     }
                 } else if (Objects.equals(VerifyExceptionEnum.FACE_COMPARE_ERROR, warningEnum)) {//人脸比对异常
-                    String faceCompareErrorRandom = ExamRecordCacheUtil.getFaceCompareErrorRandom(recordId);
-                    if (Objects.isNull(faceCompareErrorRandom)) {
-                        faceCompareErrorRandom = String.valueOf(UUID.randomUUID()).replaceAll("-", "");
-                        ExamRecordCacheUtil.setFaceCompareErrorRandom(recordId, faceCompareErrorRandom);
+                    boolean lock = false;
+                    for (int k = 0; k < SystemConstant.MAX_EXAM_STATUS_COUNT; k++) {
+                        lock = redisUtil.lock(SystemConstant.REDIS_LOCK_FACE_COMPARE_VERIFY_PREFIX + recordId,
+                                SystemConstant.REDIS_CACHE_TIME_OUT);
+                        if (lock) {
+                            try {
+                                String faceCompareErrorRandom = ExamRecordCacheUtil.getFaceCompareErrorRandom(recordId);
+                                if (Objects.isNull(faceCompareErrorRandom)) {
+                                    faceCompareErrorRandom = String.valueOf(UUID.randomUUID()).replaceAll("-", "");
+                                    ExamRecordCacheUtil.setFaceCompareErrorRandom(recordId, faceCompareErrorRandom);
+                                }
+                                ExamRecordCacheUtil
+                                        .setFaceCompareErrorNum(recordId, new AtomicInteger(ExamRecordCacheUtil.getFaceCompareErrorNum(recordId).incrementAndGet()));
+                                warningDto.setRandom(faceCompareErrorRandom);
+                                faceVerifyHistoryService
+                                        .save(id, recordId, type, photoUrl, faceCount, similarity, realness, time, exception,
+                                                faceCompareErrorRandom);
+                                Integer count = ExamRecordCacheUtil.getFaceCompareErrorNum(recordId).get();
+                                if (count > teConfig.getTotalFaceCompareErrorCount()) {
+                                    ExamRecordCacheUtil.setFaceCompareErrorRandom(recordId,
+                                            String.valueOf(UUID.randomUUID()).replaceAll("-", ""));
+                                    ExamRecordCacheUtil.setFaceCompareErrorNum(recordId, new AtomicInteger(0));
+                                    warningService.faceCompareError(warningDto);
+                                }
+                                break;
+                            } finally {
+                                if (Objects.nonNull(recordId)) {
+                                    redisUtil.releaseLock(SystemConstant.REDIS_LOCK_FACE_COMPARE_VERIFY_PREFIX + recordId);
+                                }
+                            }
+                        } else {
+                            try {
+                                Thread.sleep(500);
+                            } catch (InterruptedException e) {
+                                e.printStackTrace();
+                            }
+                        }
                     }
-                    ExamRecordCacheUtil
-                            .setFaceCompareErrorNum(recordId, new AtomicInteger(ExamRecordCacheUtil.getFaceCompareErrorNum(recordId).incrementAndGet()));
-                    warningDto.setRandom(faceCompareErrorRandom);
-                    faceVerifyHistoryService
-                            .save(id, recordId, type, photoUrl, faceCount, similarity, realness, time, exception,
-                                    faceCompareErrorRandom);
-                    Integer count = ExamRecordCacheUtil.getFaceCompareErrorNum(recordId).get();
-                    if (count > teConfig.getTotalFaceCompareErrorCount()) {
-                        ExamRecordCacheUtil.setFaceCompareErrorRandom(recordId,
-                                String.valueOf(UUID.randomUUID()).replaceAll("-", ""));
-                        ExamRecordCacheUtil.setFaceCompareErrorNum(recordId, new AtomicInteger(0));
-                        warningService.faceCompareError(warningDto);
+                    if (!lock) {
+                        tgErrorService.saveExamTgError(recordId, "faceVerifyFaceCompareError");
                     }
                 } else if (Objects.equals(VerifyExceptionEnum.EYE_CLOSE_ERROR, warningEnum)) {//闭眼检测异常
-                    String eyeCloseErrorRandom = ExamRecordCacheUtil.getEyeCloseErrorRandom(recordId);
-                    if (Objects.isNull(eyeCloseErrorRandom)) {
-                        eyeCloseErrorRandom = String.valueOf(UUID.randomUUID()).replaceAll("-", "");
-                        ExamRecordCacheUtil.setEyeCloseErrorRandom(recordId, eyeCloseErrorRandom);
+                    boolean lock = false;
+                    for (int k = 0; k < SystemConstant.MAX_EXAM_STATUS_COUNT; k++) {
+                        lock = redisUtil.lock(SystemConstant.REDIS_LOCK_EYE_CLOSE_VERIFY_PREFIX + recordId,
+                                SystemConstant.REDIS_CACHE_TIME_OUT);
+                        if (lock) {
+                            try {
+                                String eyeCloseErrorRandom = ExamRecordCacheUtil.getEyeCloseErrorRandom(recordId);
+                                if (Objects.isNull(eyeCloseErrorRandom)) {
+                                    eyeCloseErrorRandom = String.valueOf(UUID.randomUUID()).replaceAll("-", "");
+                                    ExamRecordCacheUtil.setEyeCloseErrorRandom(recordId, eyeCloseErrorRandom);
+                                }
+                                ExamRecordCacheUtil
+                                        .setEyeCloseErrorNum(recordId, new AtomicInteger(ExamRecordCacheUtil.getEyeCloseErrorNum(recordId).incrementAndGet()));
+                                warningDto.setRandom(eyeCloseErrorRandom);
+                                faceVerifyHistoryService
+                                        .save(id, recordId, type, photoUrl, faceCount, similarity, realness, time, exception,
+                                                eyeCloseErrorRandom);
+                                Integer count = ExamRecordCacheUtil.getEyeCloseErrorNum(recordId).get();
+                                if (count > teConfig.getTotalEyeCloseErrorCount()) {
+                                    ExamRecordCacheUtil.setEyeCloseErrorRandom(recordId,
+                                            String.valueOf(UUID.randomUUID()).replaceAll("-", ""));
+                                    ExamRecordCacheUtil.setEyeCloseErrorNum(recordId, new AtomicInteger(0));
+                                    warningService.eyeCloseError(warningDto);
+                                }
+                                break;
+                            } finally {
+                                if (Objects.nonNull(recordId)) {
+                                    redisUtil.releaseLock(SystemConstant.REDIS_LOCK_EYE_CLOSE_VERIFY_PREFIX + recordId);
+                                }
+                            }
+                        } else {
+                            try {
+                                Thread.sleep(500);
+                            } catch (InterruptedException e) {
+                                e.printStackTrace();
+                            }
+                        }
                     }
-                    ExamRecordCacheUtil
-                            .setEyeCloseErrorNum(recordId, new AtomicInteger(ExamRecordCacheUtil.getEyeCloseErrorNum(recordId).incrementAndGet()));
-                    warningDto.setRandom(eyeCloseErrorRandom);
-                    faceVerifyHistoryService
-                            .save(id, recordId, type, photoUrl, faceCount, similarity, realness, time, exception,
-                                    eyeCloseErrorRandom);
-                    Integer count = ExamRecordCacheUtil.getEyeCloseErrorNum(recordId).get();
-                    if (count > teConfig.getTotalEyeCloseErrorCount()) {
-                        ExamRecordCacheUtil.setEyeCloseErrorRandom(recordId,
-                                String.valueOf(UUID.randomUUID()).replaceAll("-", ""));
-                        ExamRecordCacheUtil.setEyeCloseErrorNum(recordId, new AtomicInteger(0));
-                        warningService.eyeCloseError(warningDto);
+                    if (!lock) {
+                        tgErrorService.saveExamTgError(recordId, "faceVerifyEyeCloseError");
                     }
                 }
             }
@@ -533,64 +651,127 @@ public class MqLogicServiceImpl implements MqLogicService {
                         WarningDto warningDto = new WarningDto(warningEnum, faceCount, null, recordId,
                                 String.valueOf(jsonObject.get("photoUrl")));
                         if (faceCount > 1) {//多张人脸
-                            String multipleFaceRandom = ExamRecordCacheUtil.getMultipleFaceCountErrorRandom(recordId);
-                            if (Objects.isNull(multipleFaceRandom)) {
-                                multipleFaceRandom = String.valueOf(UUID.randomUUID()).replaceAll("-", "");
-                                ExamRecordCacheUtil.setMultipleFaceCountErrorRandom(recordId, multipleFaceRandom);
+                            boolean lock = false;
+                            for (int k = 0; k < SystemConstant.MAX_EXAM_STATUS_COUNT; k++) {
+                                lock = redisUtil.lock(SystemConstant.REDIS_LOCK_FACE_MULTIPLE_VERIFY_PREFIX + recordId,
+                                        SystemConstant.REDIS_CACHE_TIME_OUT);
+                                if (lock) {
+                                    try {
+                                        String multipleFaceRandom = ExamRecordCacheUtil.getMultipleFaceCountErrorRandom(recordId);
+                                        if (Objects.isNull(multipleFaceRandom)) {
+                                            multipleFaceRandom = String.valueOf(UUID.randomUUID()).replaceAll("-", "");
+                                            ExamRecordCacheUtil.setMultipleFaceCountErrorRandom(recordId, multipleFaceRandom);
+                                        }
+                                        ExamRecordCacheUtil.setMultipleFaceCountErrorNum(recordId,
+                                                new AtomicInteger(ExamRecordCacheUtil.getMultipleFaceCountErrorNum(recordId).incrementAndGet()));
+                                        warningDto.setRandom(multipleFaceRandom);
+                                        livenessVerifyHistoryService
+                                                .save(id, recordId, type, actions, retry, startTime, finishTime, exception,
+                                                        multipleFaceRandom);
+                                        Integer count = ExamRecordCacheUtil.getMultipleFaceCountErrorNum(recordId).get();
+                                        if (count > teConfig.getMultipleFaceCountError()) {
+                                            ExamRecordCacheUtil.setMultipleFaceCountErrorRandom(recordId,
+                                                    String.valueOf(UUID.randomUUID()).replaceAll("-", ""));
+                                            ExamRecordCacheUtil.setMultipleFaceCountErrorNum(recordId, new AtomicInteger(0));
+                                            warningService.faceCountError(warningDto);
+                                        }
+                                        break;
+                                    } finally {
+                                        if (Objects.nonNull(recordId)) {
+                                            redisUtil.releaseLock(SystemConstant.REDIS_LOCK_FACE_MULTIPLE_VERIFY_PREFIX + recordId);
+                                        }
+                                    }
+                                } else {
+                                    try {
+                                        Thread.sleep(500);
+                                    } catch (InterruptedException e) {
+                                        e.printStackTrace();
+                                    }
+                                }
                             }
-                            ExamRecordCacheUtil.setMultipleFaceCountErrorNum(recordId,
-                                    new AtomicInteger(ExamRecordCacheUtil.getMultipleFaceCountErrorNum(recordId).incrementAndGet()));
-                            warningDto.setRandom(multipleFaceRandom);
-                            livenessVerifyHistoryService
-                                    .save(id, recordId, type, actions, retry, startTime, finishTime, exception,
-                                            multipleFaceRandom);
-                            Integer count = ExamRecordCacheUtil.getMultipleFaceCountErrorNum(recordId).get();
-                            if (count > teConfig.getMultipleFaceCountError()) {
-                                ExamRecordCacheUtil.setMultipleFaceCountErrorRandom(recordId,
-                                        String.valueOf(UUID.randomUUID()).replaceAll("-", ""));
-                                ExamRecordCacheUtil.setMultipleFaceCountErrorNum(recordId, new AtomicInteger(0));
-                                warningService.faceCountError(warningDto);
+                            if (!lock) {
+                                tgErrorService.saveExamTgError(recordId, "livenessVerifyMultipleFaceCountError");
                             }
                         } else if (faceCount <= 0) {
-                            String noFaceRandom = ExamRecordCacheUtil.getNoFaceCountErrorRandom(recordId);
-                            if (Objects.isNull(noFaceRandom)) {
-                                noFaceRandom = String.valueOf(UUID.randomUUID()).replaceAll("-", "");
-                                ExamRecordCacheUtil.setNoFaceCountErrorRandom(recordId, noFaceRandom);
+                            boolean lock = false;
+                            for (int k = 0; k < SystemConstant.MAX_EXAM_STATUS_COUNT; k++) {
+                                lock = redisUtil.lock(SystemConstant.REDIS_LOCK_FACE_VERIFY_PREFIX + recordId,
+                                        SystemConstant.REDIS_CACHE_TIME_OUT);
+                                if (lock) {
+                                    try {
+                                        String noFaceRandom = ExamRecordCacheUtil.getNoFaceCountErrorRandom(recordId);
+                                        if (Objects.isNull(noFaceRandom)) {
+                                            noFaceRandom = String.valueOf(UUID.randomUUID()).replaceAll("-", "");
+                                            ExamRecordCacheUtil.setNoFaceCountErrorRandom(recordId, noFaceRandom);
+                                        }
+                                        ExamRecordCacheUtil.setNoFaceCountErrorNum(recordId,
+                                                new AtomicInteger(ExamRecordCacheUtil.getMultipleFaceCountErrorNum(recordId).incrementAndGet()));
+                                        warningDto.setRandom(noFaceRandom);
+                                        livenessVerifyHistoryService
+                                                .save(id, recordId, type, actions, retry, startTime, finishTime, exception,
+                                                        noFaceRandom);
+                                        Integer count = ExamRecordCacheUtil.getNoFaceCountErrorNum(recordId).get();
+                                        if (count > teConfig.getNoFaceCountError()) {
+                                            ExamRecordCacheUtil.setNoFaceCountErrorRandom(recordId,
+                                                    String.valueOf(UUID.randomUUID()).replaceAll("-", ""));
+                                            ExamRecordCacheUtil.setNoFaceCountErrorNum(recordId, new AtomicInteger(0));
+                                            warningService.faceCountError(warningDto);
+                                        }
+                                        break;
+                                    } finally {
+                                        if (Objects.nonNull(recordId)) {
+                                            redisUtil.releaseLock(SystemConstant.REDIS_LOCK_FACE_VERIFY_PREFIX + recordId);
+                                        }
+                                    }
+                                } else {
+                                    try {
+                                        Thread.sleep(500);
+                                    } catch (InterruptedException e) {
+                                        e.printStackTrace();
+                                    }
+                                }
                             }
-                            ExamRecordCacheUtil.setNoFaceCountErrorNum(recordId,
-                                    new AtomicInteger(ExamRecordCacheUtil.getMultipleFaceCountErrorNum(recordId).incrementAndGet()));
-                            warningDto.setRandom(noFaceRandom);
-                            livenessVerifyHistoryService
-                                    .save(id, recordId, type, actions, retry, startTime, finishTime, exception,
-                                            noFaceRandom);
-                            Integer count = ExamRecordCacheUtil.getNoFaceCountErrorNum(recordId).get();
-                            if (count > teConfig.getNoFaceCountError()) {
-                                ExamRecordCacheUtil.setNoFaceCountErrorRandom(recordId,
-                                        String.valueOf(UUID.randomUUID()).replaceAll("-", ""));
-                                ExamRecordCacheUtil.setNoFaceCountErrorNum(recordId, new AtomicInteger(0));
-                                warningService.faceCountError(warningDto);
+                            if (!lock) {
+                                tgErrorService.saveExamTgError(recordId, "livenessVerifyFaceCountError");
                             }
                         }
                     } else if (Objects.equals(VerifyExceptionEnum.FACE_COMPARE_ERROR, warningEnum)) {//人脸比对异常
-                        WarningDto warningDto = new WarningDto(warningEnum, null, null, recordId,
-                                String.valueOf(jsonObject.get("photoUrl")));
-                        String faceCompareErrorRandom = ExamRecordCacheUtil.getFaceCompareErrorRandom(recordId);
-                        if (Objects.isNull(faceCompareErrorRandom)) {
-                            faceCompareErrorRandom = String.valueOf(UUID.randomUUID()).replaceAll("-", "");
-                            ExamRecordCacheUtil.setFaceCompareErrorRandom(recordId, faceCompareErrorRandom);
+                        boolean lock = false;
+                        for (int k = 0; k < SystemConstant.MAX_EXAM_STATUS_COUNT; k++) {
+                            lock = redisUtil.lock(SystemConstant.REDIS_LOCK_FACE_COMPARE_VERIFY_PREFIX + recordId,
+                                    SystemConstant.REDIS_CACHE_TIME_OUT);
+                            if (lock) {
+                                try {
+                                    WarningDto warningDto = new WarningDto(warningEnum, null, null, recordId,
+                                            String.valueOf(jsonObject.get("photoUrl")));
+                                    String faceCompareErrorRandom = ExamRecordCacheUtil.getFaceCompareErrorRandom(recordId);
+                                    if (Objects.isNull(faceCompareErrorRandom)) {
+                                        faceCompareErrorRandom = String.valueOf(UUID.randomUUID()).replaceAll("-", "");
+                                        ExamRecordCacheUtil.setFaceCompareErrorRandom(recordId, faceCompareErrorRandom);
+                                    }
+                                    ExamRecordCacheUtil.setFaceCompareErrorNum(recordId,
+                                            new AtomicInteger(ExamRecordCacheUtil.getFaceCompareErrorNum(recordId).incrementAndGet()));
+                                    warningDto.setRandom(faceCompareErrorRandom);
+                                    livenessVerifyHistoryService
+                                            .save(id, recordId, type, actions, retry, startTime, finishTime, exception,
+                                                    faceCompareErrorRandom);
+                                    Integer count = ExamRecordCacheUtil.getFaceCompareErrorNum(recordId).get();
+                                    if (count > teConfig.getTotalFaceCompareErrorCount()) {
+                                        ExamRecordCacheUtil.setFaceCompareErrorRandom(recordId,
+                                                String.valueOf(UUID.randomUUID()).replaceAll("-", ""));
+                                        ExamRecordCacheUtil.setFaceCompareErrorNum(recordId, new AtomicInteger(0));
+                                        warningService.faceCompareError(warningDto);
+                                    }
+                                    break;
+                                } finally {
+                                    if (Objects.nonNull(recordId)) {
+                                        redisUtil.releaseLock(SystemConstant.REDIS_LOCK_FACE_COMPARE_VERIFY_PREFIX + recordId);
+                                    }
+                                }
+                            }
                         }
-                        ExamRecordCacheUtil.setFaceCompareErrorNum(recordId,
-                                new AtomicInteger(ExamRecordCacheUtil.getFaceCompareErrorNum(recordId).incrementAndGet()));
-                        warningDto.setRandom(faceCompareErrorRandom);
-                        livenessVerifyHistoryService
-                                .save(id, recordId, type, actions, retry, startTime, finishTime, exception,
-                                        faceCompareErrorRandom);
-                        Integer count = ExamRecordCacheUtil.getFaceCompareErrorNum(recordId).get();
-                        if (count > teConfig.getTotalFaceCompareErrorCount()) {
-                            ExamRecordCacheUtil.setFaceCompareErrorRandom(recordId,
-                                    String.valueOf(UUID.randomUUID()).replaceAll("-", ""));
-                            ExamRecordCacheUtil.setFaceCompareErrorNum(recordId, new AtomicInteger(0));
-                            warningService.faceCompareError(warningDto);
+                        if (!lock) {
+                            tgErrorService.saveExamTgError(recordId, "livenessVerifyFaceCompareError");
                         }
                     }
                 }