Redis實現分布式鎖3-使用LUA腳本實現分布式鎖,解決原子性問題


    private static final Long SUCCESS = 1L;
    private static String script1 = "if redis.call('setNx',KEYS[1],ARGV[1])  then " +
            "   if redis.call('get',KEYS[1])==ARGV[1] then " +
            "      return redis.call('expire',KEYS[1],ARGV[2]) " +
            "   else " +
            "      return 0 " +
            "   end " +
            "end";
    private RedisScript<String> lockRedisScript1 = new DefaultRedisScript<>(script1, String.class);
    private static String script2 = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
    private RedisScript<String> unLockRedisScript = new DefaultRedisScript<>(script2, String.class);
    /**
     * 獲取鎖
     *
     * @param lockKey       redis的key
     * @param value         redis的value要求是隨機串,防止釋放其他請求的鎖
     * @param expireTime    redis的key 的過期時間  單位(秒) 防止死鎖,導致其他請求無法正常執行業務
     * @return
     */
    @Override
    public  boolean lock(String lockKey, String value, long expireTime) {
        //對非string類型的序列化
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new StringRedisSerializer());
        Object result = redisTemplate.execute(lockRedisScript1, Collections.singletonList(lockKey), value, String.valueOf(expireTime));

        return SUCCESS.equals(result);

    }

    /**
     * 釋放鎖
     *
     * @param lockKey   redis的key
     * @param value     redis的value  只有value比對一致,才能確定是本請求 加的鎖 才能正常釋放
     * @return
     */
    @Override
    public  boolean unlock(String lockKey, String value) {
        try {
            Object result = redisTemplate.execute(unLockRedisScript, Collections.singletonList(lockKey), value);
            if (SUCCESS.equals(result)) {
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM