Redisson分布式锁

并发情况下锁是我们常用的一种解决办法,实现锁的方法也有很多种。redisson作为一个redist的客户端它内部封装好了很多操作reids的命令以及对锁等的操作,简单易学非常的好用。Rddisson 实现分布式锁的用法,项目中要先连接好redis集群的配置,废话不多说直接上代码:
1.引入redisson 
 

<!-- Redission 依赖 -->
		<dependency>
			<groupId>org.redisson</groupId>
			<artifactId>redisson</artifactId>
			<version>3.17.0</version>
		</dependency>

2.切面注解类

/**
 * 分布式锁
 * @author haidi
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RedissonLock {
 
    /**
     * 分布式锁key前缀
     */
    String keyPrefix() default "";
 
    /**
     * 获取锁等待时间(默认两秒,还没获取到锁即放弃)
     */
    long waitTime() default 2;
 
    /**
     * 过期时长,防止一直占用锁
     */
    long expire() default 60;
 
    /**
     * 过期时长单位
     */
    TimeUnit timeUnit() default TimeUnit.SECONDS;
}

3.注解实现

/**
 * 分布式锁注解实现
 *
 * @author HaiDi
 */
@Aspect
@Component
@AllArgsConstructor
@Order(1)
@Slf4j
public class RedissonLockAspect {
    private final RedissonClient redissonClient;

    @Around("@annotation(distributedLock)")
    public Object lock(ProceedingJoinPoint joinPoint, RedissonLock distributedLock) {
        String[] names = ((MethodSignature) joinPoint.getSignature()).getParameterNames();
        String key = null;
        Map params = new HashMap();
        if (ArrayUtils.isNotEmpty(names)) {
            Object[] values = joinPoint.getArgs();
            for (int i = 0; i < names.length; i++) {
                params.put(names[i], values[i]);
            }
            String accountNo = (String) params.get("accountNo");
            key = String.format("distributedLock_%s", accountNo);
        }

        if (StrUtil.isNotBlank(distributedLock.keyPrefix())) {
            key = String.format("distributedLock_%s", distributedLock.keyPrefix());
        }

        RLock lock = redissonClient.getLock(key);
        boolean hasLock = false;
        try {
            hasLock = lock.tryLock(distributedLock.waitTime(), distributedLock.expire(), distributedLock.timeUnit());
            if (hasLock) {
                log.info("获取分布式锁成功,key={}", key);
                return joinPoint.proceed();
            }else {
                log.info("获取锁失败");
            }
        } catch (Throwable e) {
            log.error("切面分布式锁异常:{}", e);
        } finally {
            if (hasLock) {
                lock.unlock();
                log.info("解锁成功:{}", key);
            }
        }
        return null;
    }
}

4.使用时将注解加在方法service或者controllor上通过切面可以获取到方法入参的字段值

 


版权声明:本文为qq_41424909原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。