Redis+ lua 实现分布式锁

4 阅读1分钟
private static final String lockLua = "if redis.call('setnx',KEYS[1],ARGV[1]) == 1 then\n" +
            "    return redis.call('expire',KEYS[1],ARGV[2])\n" +
            "else\n" +
            "    return 0\n" +
            "end";
private static final String unlockLua = "if redis.call('get',KEYS[1]) == ARGV[1] then\n" +
            "    return redis.call('del',KEYS[1])\n" +
            "else\n" +
            "    return 0\n" +
            "end";



    public boolean getLock(String key, String value, int expiresTime) {
        if (StringUtils.isEmpty(key) || StringUtils.isEmpty(value) || expiresTime <= 0) {
            return false;
        }
        try {
            log.info("lock-key:{}, value:{}, expiresTime:{}", key, value, expiresTime);
            List<String> keys = new ArrayList<String>(1);
            keys.add(key);

            List<String> args = new ArrayList<String>(2);
            args.add(value);
            args.add(String.valueOf(expiresTime));
            Long result = (Long) jimClient.evalsha(jimClient.scriptLoad(lockLua), keys, args, false, ScriptOutputType.INTEGER);
            if (result == 1) {
                log.info("lock-key:{}, value:{}, expiresTime:{} lock success", key, value, expiresTime);
                return true;
            } else {
                log.info("lock-key:{}, value:{}, expiresTime:{} lock failed", key, value, expiresTime);
                return false;
            }

        } catch (Exception ex) {
            log.warn("lock-key:{}, value:{} failed", key, value, ex);
            //加锁失败
            return false;
        }
    }

    public boolean unLock(String key, String value) {
        if (StringUtils.isEmpty(key) || StringUtils.isEmpty(value)) {
            return false;
        }
        try {
            log.info("unLock-key:{}, value:{}", key, value);
            List<String> keys = new ArrayList<String>(1);
            keys.add(key);
            List<String> args = new ArrayList<String>(1);
            args.add(value);
            Long result = (Long) jimClient.evalsha(jimClient.scriptLoad(unlockLua), keys, args, false, ScriptOutputType.INTEGER);
            if (result == 1) {
                log.info("unLock-key:{}, value:{} unlock success", key, value);
                return true;
            } else {
                log.info("unLock-key:{}, value:{} unlock failed", key, value);
                return false;
            }
        } catch (Exception ex) {
            log.warn("unLock-key:{}, value:{} failed", key, value, ex);
            //解锁失败
            return false;
        }
    }