Redis分布式鎖 基于redis.eval

實現(xiàn)方法:使用redis的eval執(zhí)行l(wèi)ua腳本

EVAL script numkeys key [key ...] arg [arg ...]

從 Redis 2.6.0 版本開始,通過內(nèi)置的 Lua 解釋器,可以使用 EVAL 命令對 Lua 腳本進行求值。

Java代碼

package com.label.practice;

import com.google.common.collect.Lists;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import java.util.List;

/**
 * Redis分布式鎖
 *
 * @author libiao
 * @since 2017-12-05
 */
@Log4j2
public class RedisClient {
    private JedisPool jedisPool = null;

    public long del(String... keys) {
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.del(keys);
        }
    }

    public boolean set(String key, String value) {
        try (Jedis jedis = jedisPool.getResource()) {
            return StringUtils.equals(jedis.set(key, value), Constant.SET_SUCCESS);
        }
    }

    public boolean setNxEx(String key, String value, int seconds) {
        try (Jedis jedis = jedisPool.getResource()) {
            return StringUtils.equals(jedis.set(key, value, Constant.SET_IF_NOT_EXISTS, Constant.SET_WITH_EXPIRES, seconds), Constant.SET_SUCCESS);
        }
    }

    public String get(String key) {
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.get(key);
        }
    }

    public Object eval(String script, List<String> keyList, List<String> valueList) {
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.eval(script, keyList, valueList);
        }

    }

    public RedisLock getRedisLock() {
        return new RedisLock();
    }

    public class RedisLock {
        private static final String lockScript = "if (redis.call('exists',KEYS[1]) == 0 or redis.call('get',KEYS[1]) == ARGV[2]) then return redis.call('setex',KEYS[1],ARGV[1],ARGV[2]) else return -1 end";
        public static final String unlockScript = "if (redis.call('exists',KEYS[1]) == 0 or redis.call('get',KEYS[1]) == ARGV[1]) then return redis.call('del',KEYS[1]) else return -1 end";

        public boolean tryLock(String key, String requestId, int seconds) {
            try (Jedis jedis = jedisPool.getResource()) {
                Object eval = jedis.eval(lockScript, Lists.newArrayList(key), Lists.newArrayList(String.valueOf(seconds), requestId));
                log.info(eval);
                if (null != eval && StringUtils.equals(Constant.SET_SUCCESS, String.valueOf(eval))) {
                    return true;
                }
            }
            return false;
        }

        public boolean unLock(String key, String requestId) {
            try (Jedis jedis = jedisPool.getResource()) {

                Object eval = jedis.eval(unlockScript, Lists.newArrayList(key), Lists.newArrayList(requestId));
                log.info(eval);
                if (null == eval) {
                    return false;
                }
                int affectedRows = Integer.parseInt(String.valueOf(eval));
                if (1 == affectedRows || 0 == affectedRows) {
                    return true;
                }
            }
            return false;
        }
    }

    public class Constant {
        public static final String SET_SUCCESS = "OK";
        public static final String SET_IF_NOT_EXISTS = "NX";
        public static final String SET_WITH_EXPIRES = "EX";
    }

    public static RedisClient getInstance() {
        return RedisClientPlaceHolder.redisClient;
    }

    private RedisClient() {
        GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
        poolConfig.setMaxIdle(10);
        poolConfig.setMaxTotal(50);
        poolConfig.setLifo(false);
        poolConfig.setTestOnBorrow(true);
        poolConfig.setTestWhileIdle(true);
        poolConfig.setMaxWaitMillis(5000);


        jedisPool = new JedisPool(poolConfig, "w10979.sit.wdds.redis.com", 10979);
    }

    private static class RedisClientPlaceHolder {
        private static RedisClient redisClient = new RedisClient();
    }
}

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容