@Slf4j
@Aspect
@Component
public class SynchronizeLockAspect {
private static final String KEY = "thread_lock";
private final ThreadLocal<String> threadLocal = new ThreadLocal<>();
private final StringRedisTemplate stringRedisTemplate;
public SynchronizeLockAspect(StringRedisTemplate stringRedisTemplate) {
this.stringRedisTemplate = stringRedisTemplate;
}
@Pointcut("@annotation(com.rixin.qlczbackend.annotation.SynchronizeLock)")
public void pointCut() {
}
@Around("pointCut()")
private Object checkLocked(ProceedingJoinPoint joinPoint) {
// 前置加锁
threadLocal.set(UUID.randomUUID().toString());
// 设置超时避免死锁
Boolean flag = stringRedisTemplate.opsForValue().setIfAbsent(KEY, threadLocal.get(), 1, TimeUnit.MINUTES);
if (flag == null || !flag) {
return BaseResponseVO.error(ResponseCodeEnum.INTERNAL_ERROR_CODE.getCode(), "系统繁忙,请重试");
}
log.info("add lock {}", threadLocal.get());
try {
return joinPoint.proceed();
} catch (Throwable throwable) {
log.error(throwable.getMessage(), throwable);
return BaseResponseVO.error(ResponseCodeEnum.INTERNAL_ERROR_CODE.getCode(), ResponseCodeEnum.INTERNAL_ERROR_CODE.getMessage());
} finally {
// 后置解锁
String val = stringRedisTemplate.opsForValue().get(KEY);
if (val != null && val.equals(threadLocal.get())) {
stringRedisTemplate.delete(KEY);
log.info("unlock {} success", threadLocal.get());
} else {
log.info("cannot find lock {}", threadLocal.get());
}
threadLocal.remove();
}
}
}
自己实现的一个redis锁注解
于 2020-09-14 09:41:03 首次发布