分布锁(Redis+lua)

2021-04-29  本文已影响0人  超人001

上锁

EX second :设置键的过期时间为 second 秒。 SET key value EX second 效果等同于 SETEX key second value 。
PX millisecond :设置键的过期时间为 millisecond 毫秒。 SET key value PX millisecond 效果等同于 PSETEX key millisecond value 。
NX :只在键不存在时,才对键进行设置操作。 SET key value NX 效果等同于 SETNX key value 。
XX :只在键已经存在时,才对键进行设置操作。

public static boolean lock(String key,String lockValue,int expire){
      if(null == key){
          return false;
      }
      try {
          Jedis jedis = getJedisPool().getResource();
          String res = jedis.set(key,lockValue,"NX","EX",expire);
          jedis.close();
          return res!=null && res.equals("OK");
      } catch (Exception e) {
          return false;
      }
  }

lua脚本

if redis.call('get', KEYS[1]) == ARGV[1] 
    then 
        return redis.call('del', KEYS[1]) 
    else 
        return 0 
end

释放锁

private static final Long lockReleaseOK = 1L;
static String luaScript = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end";// lua脚本,用来释放分布式锁
 
public static boolean releaseLock(String key ,String lockValue){
    if(key == null || lockValue == null) {
        return false;
    }
    try {
        Jedis jedis = getJedisPool().getResource();
        Object res =jedis.eval(luaScript,Collections.singletonList(key),Collections.singletonList(lockValue));
        jedis.close();
        return res!=null && res.equals(lockReleaseOK);
    } catch (Exception e) {
        return false;
    }
}

unLock.lua脚本文件

local lockkey = KEYS[1]
--唯一随机数
local uid = KEYS[2]
--失效时间,如果是当前线程,也是续期时间
local time = KEYS[3]

if redis.call('set',lockkey,uid,'nx','px',time)=='OK' then
return 'OK'
else
    if redis.call('get',lockkey) == uid then
       if redis.call('EXPIRE',lockkey,time/1000)==1 then
       return 'OOKK'
       end
    end
end

java 调用脚本文件

  public void luaUnLock() throws Exception{
        Jedis jedis = new Jedis("localhost") ;
        InputStream input = new FileInputStream("unLock.lua");
        byte[] by = new byte[input.available()];
        input.read(by);
        String script = new String(by);
        Object obj = jedis.eval(script, Arrays.asList("key","123"), Arrays.asList(""));
        System.out.println("执行结果 " + obj);
    }

main方法操作

lock("item-01","1",20000);
Thread.sleep(2000);
releaseLock("item-01","1");
上一篇 下一篇

猜你喜欢

热点阅读