美文网首页
分布锁(Redis+lua)

分布锁(Redis+lua)

作者: 超人001 | 来源:发表于2021-04-29 17:56 被阅读0次

    上锁

    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");
    

    相关文章

      网友评论

          本文标题:分布锁(Redis+lua)

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