美文网首页
redis+Lua实现分布式锁

redis+Lua实现分布式锁

作者: 不爱写代码的程序员 | 来源:发表于2018-12-08 23:37 被阅读0次

    1.方法lock(String lock, int expire) :获取锁

    expire,锁的过期时间

    setnx(),只有当lock不存在时才会赋值,赋值成功返回1,赋值失败返回0


     public boolean lock(String lock, int expire) throws Exception {

            Assert.notNull(lock, "lock must not be null");

            long expireTime = getExpireTime(expire);

            return RedisUtils.setnx(lock, expireTime) ==1;

        }


    2.方法softUnlock(String lock):解锁,只有当锁过期时才会解锁

    使用Lua脚本script,获取锁的状态以及解锁,这两步操作必须为原子性操作


    public boolean softUnlock(String lock)throws Exception {

            Assert.notNull(lock, "lock must not be null");

            String script ="if redis.call('exists', KEYS[1]) == 1 then if redis.call('get', KEYS[1]) < ARGV[1] then redis.call('del', KEYS[1]) return 1 else return 0 end else return 1 end";

           String currentTime = String.valueOf(System.currentTimeMillis());

           String expireCode = String.valueOf(RedisUtils.eval(script, lock, currentTime));

           return RELEASE_SUCCESS.equals(expireCode)

    }


    3.方法hardUnlock(String lock):解锁,不关心锁的是否过期


        public boolean hardUnlock(String lock) throws Exception {

                Assert.notNull(lock, "lock must not be null");

                RedisUtils.del(lock);

                return true;

        }


    4.方法getLockStatus(String lock):获取锁的状态


    public boolean getLockStatus(String lock) throws Exception {

            String value = RedisUtils.get(lock);

            return value ==null || Long.parseLong(value) < System.currentTimeMillis();

        }


    5.方法autoIncrLock(String lock):锁的值自加1,如果锁本身不存在,默认从0开始


    public String autoIncrLock(String lock) throws Exception {

            Assert.notNull(lock, "lock must not be null");

            lock = assembleKey(AUTO, lock);

            String script ="if redis.call('exists',KEYS[1]) == 1 then redis.call('incr', KEYS[1]) else redis.call('set',KEYS[1],ARGV[1]) end return redis.call('get', KEYS[1])";

            String value = String.valueOf(RedisUtils.eval(script, lock, "1"));

            logger.info("autoIncrLock success#lock={},value={}", lock, value);

            return value;

        }


    6.方法autoDecrLock(String lock):锁的值自减1,如果锁本身不存在,默认从0开始


    public String autoDecrLock(String lock) throws Exception {

            Assert.notNull(lock, "lock must not be null");

            lock = assembleKey(AUTO, lock);

            String script ="if redis.call('exists',KEYS[1]) == 1 then redis.call('decr', KEYS[1]) else redis.call('set',KEYS[1],ARGV[1]) end return redis.call('get', KEYS[1])";

            String value = String.valueOf(RedisUtils.eval(script, lock, "-1"));

            logger.info("autoDecrLock success#lock={},value={}", lock, value);

            return value;

        }


    7.方法softUnlockAuto(String lock):解锁,只有当锁过期时才会解锁


    public boolean softUnlockAuto(String lock) throws Exception {

            Assert.notNull(lock, "lock must not be null");

            lock = assembleKey(AUTO, lock);

            String script ="if redis.call('exists', KEYS[1]) == 1 then if redis.call('get', KEYS[1]) <= ARGV[1] then redis.call('del', KEYS[1]) return 1 else return 0 end else return 1 end";

            String code = String.valueOf(RedisUtils.eval(script, lock, "0"));         

            return RELEASE_SUCCESS.equals(code);

    }


    8.方法hardUnlockAuto(String lock):解锁,不关心当前锁的状态


    public boolean hardUnlockAuto(String lock) throws Exception {

                    lock = assembleKey(AUTO, lock);

                    return hardUnlock(lock);

        }


    9.方法String assembleKey(String... section):组装key


    public String assembleKey(String... section) throw Exception {

            List sections =new ArrayList(Arrays.asList(section));

            Joiner joiner = Joiner.on(KEY_PRE_CON_SIGN).skipNulls();

            return joiner.join(sections);

        }


    10.方法getExpireTime(int expire): 获取过期时间


    private String getExpireTime(int expire) throws Exception {

            Assert.isTrue(expire > 0, "expire must be greater than 0");

            long expireTime = System.currentTimeMillis() + expire +1;

            return String.valueOf(expireTime);

        }

    相关文章

      网友评论

          本文标题:redis+Lua实现分布式锁

          本文链接:https://www.haomeiwen.com/subject/pvochqtx.html