123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- package cn.com.qmth.examcloud.web.helpers;
- import java.util.List;
- import java.util.concurrent.TimeUnit;
- import org.apache.commons.lang.StringUtils;
- import org.assertj.core.util.Arrays;
- import com.google.common.collect.Lists;
- 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.interceptor.SeqlockInterceptor;
- 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), "_");
- int timeout = 60 * 2;
- if (getRedisClient().setIfAbsent(key, ThreadLocalUtil.getTraceId(), timeout)) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("locked");
- }
- @SuppressWarnings("unchecked")
- List<String> keyList = (List<String>) ServletUtil.getRequest()
- .getAttribute(HttpServletRequestAttribute.$_CUSTOM_SEQUENCE_LOCK.name());
- if (null == keyList) {
- keyList = Lists.newArrayList();
- }
- keyList.add(key);
- ServletUtil.getRequest().setAttribute(
- HttpServletRequestAttribute.$_CUSTOM_SEQUENCE_LOCK.name(), keyList);
- } else {
- Long expire = getRedisClient().getExpire(key, TimeUnit.SECONDS);
- if (null == expire || expire > timeout) {
- getRedisClient().delete(key);
- }
- throw new SequenceLockException("请求等待,请稍后重试!");
- }
- }
-
- /**
- * 释放锁<br>
- * 接口调用不要调用此方法释放锁,此锁会在拦截器<{@link SeqlockInterceptor}中释放.
- *
- * @author WANGWEI
- * @param args
- */
- public static void releaseLock(Object... args) {
- String key = LOCK_PREFIX + StringUtils.join(Arrays.asList(args), "_");
- getRedisClient().expire((String) key, 100, TimeUnit.MILLISECONDS);
- @SuppressWarnings("unchecked")
- List<String> keyList = (List<String>) ServletUtil.getRequest()
- .getAttribute(HttpServletRequestAttribute.$_CUSTOM_SEQUENCE_LOCK.name());
- if (null != keyList) {
- if (keyList.contains(key)) {
- keyList.remove(key);
- }
- }
- }
-
- /**
- * 获取顺序请求锁<br>
- *
- * @param args
- * @throws SequenceLockException
- * 获取锁失败时抛出异常
- */
- public static void getLockSimple(Object... args) throws SequenceLockException {
- String key = LOCK_PREFIX + StringUtils.join(Arrays.asList(args), "_");
- int timeout = 60 * 2;
- if (!getRedisClient().setIfAbsent(key, ThreadLocalUtil.getTraceId(), timeout)) {
- Long expire = getRedisClient().getExpire(key, TimeUnit.SECONDS);
- if (null == expire || expire > timeout) {
- getRedisClient().delete(key);
- }
- throw new SequenceLockException("请求等待,请稍后重试!");
- }
- }
-
- /**
- * 释放锁<br>
- * 接口调用不要调用此方法释放锁,此锁会在拦截器<{@link SeqlockInterceptor}中释放.
- *
- * @author WANGWEI
- * @param args
- */
- public static void releaseLockSimple(Object... args) {
- String key = LOCK_PREFIX + StringUtils.join(Arrays.asList(args), "_");
- getRedisClient().delete(key);
- }
- }
|