WANG 6 лет назад
Родитель
Сommit
6ef68fbd40

+ 22 - 0
src/main/java/cn/com/qmth/examcloud/web/exception/SequenceLockException.java

@@ -0,0 +1,22 @@
+package cn.com.qmth.examcloud.web.exception;
+
+/**
+ * 顺序请求异常
+ *
+ * @author WANGWEI
+ * @date 2019年2月22日
+ * @Copyright (c) 2018-2020 WANGWEI [QQ:522080330] All Rights Reserved.
+ */
+public class SequenceLockException extends RuntimeException {
+
+	private static final long serialVersionUID = 6799267531884646906L;
+
+	public SequenceLockException() {
+		super();
+	}
+
+	public SequenceLockException(String message) {
+		super(message);
+	}
+
+}

+ 73 - 0
src/main/java/cn/com/qmth/examcloud/web/helpers/SequenceLockHelper.java

@@ -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());
+	}
+
+}