并发情况下锁是我们常用的一种解决办法,实现锁的方法也有很多种。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版权协议,转载请附上原文出处链接和本声明。