Redis分佈式鎖基於JEDIS和Spring BOOT

本文只有代碼,具體的鎖概念什麼的可以搜一下,代碼加入項目後,記得驗證一下,不要坑到大家就行。

1、基於JEDIS


  // 分佈式鎖
  /**
   * LOCK_SUCCESS:成功加鎖.
   * 
   * @since JDK 1.8
   */
  private static final String LOCK_SUCCESS = "OK";
  /**
   * SET_IF_NOT_EXIST:NX,意思是SET IF NOT
   * EXIST,即當key不存在時,我們進行set操作;若key已經存在,則不做任何操作;.
   * 
   * @since JDK 1.8
   */
  private static final String SET_IF_NOT_EXIST = "NX";
  /**
   * SET_WITH_EXPIRE_TIME:PX,意思是我們要給這個key加一個過期的設置,具體時間由第五個參數決定。.
   * 
   * @since JDK 1.8
   */
  private static final String SET_WITH_EXPIRE_TIME = "PX";
  /**
   * RELEASE_SUCCESS:成功解鎖標誌.
   * 
   * @since JDK 1.8
   */
  private static final Long RELEASE_SUCCESS = 1L;

  /**
   * tryGetDistributedLock:嘗試獲取分佈式鎖. <br/>
   *
   * @author atc
   * @param lockKey
   *          鎖
   * @param requestId
   *          請求標識
   * @param expireTime
   *          鎖過期時間(自動刪除,單位毫秒)
   * @return 是否加鎖成功
   * @since JDK 1.8
   */
  public boolean tryGetDistributedLock(String lockKey, String requestId,
      int expireTime) {
    Jedis jedis = null;
    try {
      jedis = jedisPool.getResource();
      String result = jedis.set(lockKey, requestId, SET_IF_NOT_EXIST,
          SET_WITH_EXPIRE_TIME, expireTime);
      if (LOCK_SUCCESS.equals(result)) {
        return true;
      }
      return false;
    } catch (Exception e) {
      e.printStackTrace();
      return false;
    } finally {
      if (null != jedis) {
        jedis.close();
      }
    }
  }

  /**
   * releaseDistributedLock:釋放分佈式鎖. <br/>
   *
   * @author atc
   * @param lockKey
   *          鎖
   * @param requestId
   *          請求標識
   * @return 是否解鎖成功
   * @since JDK 1.8
   */
  public boolean releaseDistributedLock(String lockKey, String requestId) {
    Jedis jedis = null;
    try {
      jedis = jedisPool.getResource();
      // 判斷鎖是否存在
      if (jedis.exists(lockKey)) {
        // 存在則解鎖
        String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return "
            + "redis.call('del', KEYS[1]) else return 0 end";

        Long result = (Long) jedis.eval(script,
            Collections.singletonList(lockKey),
            Collections.singletonList(requestId));
        if (RELEASE_SUCCESS.equals(result)) {
          return true;
        }
        return false;
      } else {
        return true;
      }
    } catch (Exception e) {
      e.printStackTrace();
      return false;
    } finally {
      if (null != jedis) {
        jedis.close();
      }
    }
  }

2、基於SPRING BOOT

// 分佈式鎖

  /**
   * RELEASE_SUCCESS:成功解鎖標誌.
   * 
   * @since JDK 1.8
   */
  private static final Long RELEASE_SUCCESS = 1L;

  /**
   * tryGetDistributedLock:嘗試獲取分佈式鎖. <br/>
   *
   * @author atc
   * @param lockKey
   *          鎖
   * @param requestId
   *          請求標識
   * @param expireTime
   *          鎖過期時間(自動刪除,單位毫秒)
   * @return 是否加鎖成功
   * @since JDK 1.8
   */
  public boolean tryGetDistributedLock(String lockKey, String requestId,
      int expireTime) {
    try {
      return stringRedisTemplate.opsForValue().setIfAbsent(lockKey, requestId,
          expireTime, TimeUnit.MILLISECONDS);
    } catch (Exception e) {
      e.printStackTrace();
      return false;
    }
  }

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

  /**
   * releaseDistributedLock:釋放分佈式鎖. <br/>
   *
   * @author atc
   * @param lockKey
   *          鎖
   * @param requestId
   *          請求標識
   * @return 是否解鎖成功
   * @since JDK 1.8
   */
  public boolean releaseDistributedLock(String lockKey, String requestId) {
    try {
      // 判斷鎖是否存在
      if (exists(lockKey)) {
        // 存在則解鎖
        Object execute = redisTemplate.execute(
            (RedisConnection connection) -> connection.eval(script.getBytes(),
                org.springframework.data.redis.connection.ReturnType.INTEGER, 1,
                lockKey.getBytes(), requestId.getBytes()));
        return RELEASE_SUCCESS.equals(execute);
      } else {
        return true;
      }
    } catch (Exception e) {
      e.printStackTrace();
      return false;
    }
  }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章