|
@@ -0,0 +1,73 @@
|
|
|
+package cn.com.qmth.examcloud.web.helpers;
|
|
|
+
|
|
|
+import org.apache.commons.lang.StringUtils;
|
|
|
+import org.assertj.core.util.Arrays;
|
|
|
+
|
|
|
+import cn.com.qmth.examcloud.commons.logging.ExamCloudLog;
|
|
|
+import cn.com.qmth.examcloud.commons.logging.ExamCloudLogFactory;
|
|
|
+import cn.com.qmth.examcloud.commons.util.ThreadLocalUtil;
|
|
|
+import cn.com.qmth.examcloud.web.enums.HttpServletRequestAttribute;
|
|
|
+import cn.com.qmth.examcloud.web.exception.SequenceLockException;
|
|
|
+import cn.com.qmth.examcloud.web.redis.RedisClient;
|
|
|
+import cn.com.qmth.examcloud.web.support.ServletUtil;
|
|
|
+import cn.com.qmth.examcloud.web.support.SpringContextHolder;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 并发顺序锁
|
|
|
+ *
|
|
|
+ * @author WANGWEI
|
|
|
+ * @date 2019年2月22日
|
|
|
+ * @Copyright (c) 2018-2020 WANGWEI [QQ:522080330] All Rights Reserved.
|
|
|
+ */
|
|
|
+public class SequenceLockHelper {
|
|
|
+
|
|
|
+ private static final ExamCloudLog LOG = ExamCloudLogFactory.getLog(SequenceLockHelper.class);
|
|
|
+
|
|
|
+ private static final String LOCK_PREFIX = "$_LOCK_C:";
|
|
|
+
|
|
|
+ private static RedisClient redisClient;
|
|
|
+
|
|
|
+ private static RedisClient getRedisClient() {
|
|
|
+ if (null == redisClient) {
|
|
|
+ redisClient = SpringContextHolder.getBean(RedisClient.class);
|
|
|
+ }
|
|
|
+
|
|
|
+ return redisClient;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取顺序请求锁<br>
|
|
|
+ *
|
|
|
+ * @param args
|
|
|
+ * @throws SequenceLockException
|
|
|
+ * 获取锁失败时抛出异常
|
|
|
+ */
|
|
|
+ public static void getLock(Object... args) throws SequenceLockException {
|
|
|
+
|
|
|
+ String key = LOCK_PREFIX + StringUtils.join(Arrays.asList(args), "_");
|
|
|
+
|
|
|
+ if (getRedisClient().setIfAbsent(key, ThreadLocalUtil.getTraceId(), 60 * 5)) {
|
|
|
+ if (LOG.isDebugEnabled()) {
|
|
|
+ LOG.debug("locked");
|
|
|
+ }
|
|
|
+ ServletUtil.getRequest()
|
|
|
+ .setAttribute(HttpServletRequestAttribute.$_CUSTOM_SEQUENCE_LOCK.name(), key);
|
|
|
+ } else {
|
|
|
+ throw new SequenceLockException("请求等待,请稍后重试!");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 释放锁
|
|
|
+ *
|
|
|
+ * @author WANGWEI
|
|
|
+ * @param args
|
|
|
+ */
|
|
|
+ public static void releaseLock(Object... args) {
|
|
|
+ String key = LOCK_PREFIX + StringUtils.join(Arrays.asList(args), "_");
|
|
|
+ getRedisClient().delete(key);
|
|
|
+ ServletUtil.getRequest()
|
|
|
+ .removeAttribute(HttpServletRequestAttribute.$_CUSTOM_SEQUENCE_LOCK.name());
|
|
|
+ }
|
|
|
+
|
|
|
+}
|