使用redis setnx命令结合lua脚本实现分布式锁功能

使用redis setnx命令结合lua脚本实现分布式锁功能

public Map<String, List<catalog2Vo>> getCatalogJsonFromDBWithRedisLock() {
        //抢占分布式锁
        String uuid = UUID.randomUUID().toString();//设置锁的唯一id
        Boolean lockBoolean = redisTemplate.opsForValue().setIfAbsent("redisLock",uuid,60,TimeUnit.SECONDS);//设置过期时间,这里的setIfAbsent相当于setnx命令
        if (lockBoolean){
            System.out.println("success to obtain redisLock");
            //加锁成功,执行业务,设置过期时间,与加锁同步,获取锁与删除锁这两个步骤须是原子操作,结合lua脚本操作
            Map<String, List<catalog2Vo>> dataFromDB;
            try{
                dataFromDB = getDataFromDB();//业务逻辑
            }
            finally {//释放锁
                String script="if redis.call(\"get\",KEYS[1]) == ARGV[1]\n" +
                        "then\n" +
                        "    return redis.call(\"del\",KEYS[1])\n" +
                        "else\n" +
                        "    return 0\n" +
                        "end";
                redisTemplate.execute(new DefaultRedisScript<>(script,Long.class),Arrays.asList("redisLock"),uuid);
            }
            return dataFromDB;
        }else {
            //加锁失败,重试
            System.out.println("fail to obtain the redisLock,ready to repeated...");
            try{
                Thread.sleep(200);
            }catch (Exception e){
                System.out.println(e.getStackTrace());
            }
            return getCatalogJsonFromDBWithRedisLock();
        }
    }
上一篇:Redis分布式锁—SETNX+Lua脚本实现篇


下一篇:分布式锁分析:使用Redis实现分布式事务中的锁机制