原理:基于切面编程实现通过注解的方式实现redis锁
代码如下:
依赖:
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.7.3</version>
</dependency>
注解代码
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface RedisLock {
/**
* 集合名
* @return
*/
String key();
/**
* 锁名
*
* @return
*/
String lockName();
long expire() default 1800L;
TimeUnit timeUnit() default TimeUnit.SECONDS;
}
切面类,其中的BusinessException为自定义异常类,可以自己实现
@Aspect
@Component
public class RedisLockAspect {
@Autowired
private RedissonClient redissonClient;
private static final String REDIS_PREFIX = "redisson_lock:";
@Around("@annotation(redisLock)")
public Object around(ProceedingJoinPoint joinPoint, RedisLock redisLock) {
String key = redisLock.key();
String lockName = redisLock.lockName();
RLock rLock = redissonClient.getLock(REDIS_PREFIX + lockName + ":" + key);
rLock.expire(redisLock.expire(), redisLock.timeUnit());
boolean b = false;
try {
//拿不到锁立即返回
b = rLock.tryLock(0, TimeUnit.SECONDS);
if (b) {
return joinPoint.proceed();
} else {
throw new BusinessException("当前页面有人正在进行操作,请稍后重试...");
}
} catch (BusinessException e) {
throw new BusinessException(e.getErrorMessage());
} catch (Throwable e) {
throw new BusinessException("当前页面有人正在进行操作,请稍后重试...");
} finally {
//释放锁
if (b) {
rLock.unlock();
}
}
}
}
使用方法