Redission实现分布式锁

技术实现

  • redission: Redis官方推荐的Java版的Redis客户端
  • aop: 面向切面编程

1. 导入依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson</artifactId>
            <version>3.16.0</version>
        </dependency>

2. 配置RedissonClient

@Configuration
public class RedissonConfig {

    @Bean
    public RedissonClient redissonClient() {
        Config config = new Config();
        config.useSingleServer().setAddress("redis://ip:port");
        config.useSingleServer().setPassword("password");
        return Redisson.create(config);
    }

}

3. 定义锁注解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RedisLock {

    String key();

    long timeout() default 0;

    long waitTime() default 1000L;
}
  • key: 当前锁的名称
  • timeout: 锁的超时时间
  • waitTime: 锁的等待时间

4. 解析注解

@Aspect
@Component
public class RedisLockAspect {

    private Logger logger = LoggerFactory.getLogger(RedisLockAspect.class);

    private static final String PREFIX = "lock:";

    @Autowired
    private RedissonClient redissonClient;

    @Pointcut("@annotation(com.example.demo.annotation.RedisLock)")
    public void pointcut(){};

    @Around("pointcut()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        MethodSignature signature = (MethodSignature) pjp.getSignature();
        RedisLock readLock = signature.getMethod().getAnnotation(RedisLock.class);
        String name = PREFIX + readLock.key();
        RLock lock = redissonClient.getLock(name);
        boolean lockRes;
        if (readLock.timeout() == 0) {
            lockRes = lock.tryLock(readLock.waitTime(), TimeUnit.MILLISECONDS);
        } else {
            lockRes = lock.tryLock(readLock.waitTime(), readLock.timeout(), TimeUnit.MILLISECONDS);
        }
        if (lockRes) {
            try {
                logger.info("获取redisLock锁成功. name: {}, waitTime: {}, timeout: {}", name, readLock.waitTime(), readLock.timeout());
                return pjp.proceed();
            } finally {
                lock.unlock();
                logger.info("释放redisLock锁. name: {}", name);
            }
        }
        throw new RuntimeException("操作正在处理中...");
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。