中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么在SpringBoot中利用redis實現分布式鎖

發布時間:2021-01-25 15:52:30 來源:億速云 閱讀:195 作者:Leah 欄目:開發技術

這篇文章將為大家詳細講解有關怎么在SpringBoot中利用redis實現分布式鎖,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。

1、準備

使用redis實現分布式鎖,需要用的setnx(),所以需要集成Jedis

需要引入jar,jar最好和redis的jar版本對應上,不然會出現版本沖突,使用的時候會報異常redis.clients.jedis.Jedis.set(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)Ljava/lang/String;

我使用的redis版本是2.3.0,Jedis使用的是3.3.0

<dependency>
      <groupId>redis.clients</groupId>
      <artifactId>jedis</artifactId>
      <version>3.3.0</version>
    </dependency>

2、配置參數

spring:
  redis:
    host: localhost
    port: 6379
    password: root
    timeout: 5000
    # Redis數據庫索引(默認為0)
    database: 0
    # 連接池最大連接數(使用負值表示沒有限制)
    jedis:
      pool:
      # 連接池最大連接數(使用負值表示沒有限制)
      max-active: 8
      # 連接池最大阻塞等待時間(使用負值表示沒有限制)
      max-wait: -1
      # 連接池中的最大空閑連接
      max-idle: 8
      # 連接池中的最小空閑連接
      min-idle: 0
      # 獲取連接時檢測是否可用
      testOnBorrow: true

3、配置JedisPool

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
 
/**
 * Jedis配置項
 * @autho ConnorSong
 * @date 2021/1/21 9:55 上午
 */
@Configuration
@Slf4j
public class JedisPoolCinfigration {
 
  @Bean
  public JedisPoolConfig jedisPoolConfig(@Value("${spring.redis.jedis.pool.max-active}") int maxActive,
                      @Value("${spring.redis.jedis.pool.max-idle}") int maxIdle,
                      @Value("${spring.redis.jedis.pool.min-idle}") int minIdle,
                      @Value("${spring.redis.jedis.pool.max-wait}") long maxWaitMillis,
                      @Value("${spring.redis.jedis.pool.testOnBorrow}") boolean testOnBorrow) {
    JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
    jedisPoolConfig.setMaxTotal(maxActive);
    jedisPoolConfig.setMaxIdle(maxIdle);
    jedisPoolConfig.setMinIdle(minIdle);
    jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
    jedisPoolConfig.setTestOnBorrow(testOnBorrow);
 
    return jedisPoolConfig;
  }
 
  @Bean
  public JedisPool jedisPool(@Value("${spring.redis.host}") String host,
                @Value("${spring.redis.password}") String password,
                @Value("${spring.redis.port}") int port,
                @Value("${spring.redis.timeout}") int timeout, JedisPoolConfig jedisPoolConfig) {
 
    log.info("=====創建JedisPool連接池=====");
    if (StringUtils.isNotEmpty(password)) {
      return new JedisPool(jedisPoolConfig, host, port, timeout, password);
    }
 
    return new JedisPool(jedisPoolConfig, host, port, timeout);
 
  }
}

4、分布式鎖工具類

import lombok.extern.slf4j.Slf4j;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.params.SetParams;
 
import java.util.Collections;
 
/**
 * jedis分布式鎖工具類
 * @autho ConnorSong
 * @date 2021/1/20 6:26 下午
 */
@Slf4j
public class JedisLockUtils {
 
  private static final String LOCK_SUCCESS = "OK";
 
  private static final Long RELEASE_SUCCESS = 1L;
  /**
   * 嘗試獲取分布式鎖
   * @param jedis Redis客戶端
   * @param lockKey 鎖
   * @param lockValue value
   * @param expireTime 超期時間(秒)
   * @return 是否獲取成功
   */
  public static boolean tryGetLock(Jedis jedis, String lockKey, String lockValue, int expireTime) {
    log.info("----獲取Jedis分布式鎖----lockKey:{}", lockKey);
 
    try {
      //方案一,具有原子性,并且可以設置過期時間,避免拿到鎖后,業務代碼出現異常,無法釋放鎖
      String result = jedis.set(lockKey, lockValue, new SetParams().nx().ex(expireTime));
      if (LOCK_SUCCESS.equals(result)) {
        return true;
      }
      return false;
      //方案二,setnx()具有原子性,但是有后續判斷,整體不具有原子性,不能設置過期時間
//      //setnx(lockkey, 當前時間+過期超時時間),如果返回 1,則獲取鎖成功;如果返回 0 則沒有獲取到鎖
//      String value = new Date().getTime() + expireTime + "";
//      if(1 == jedis.setnx(lockKey, value)){
//        return true;
//      }else{
//        String oldExpireTime = jedis.get(lockKey);
//        if(Long.valueOf(oldExpireTime)< new Date().getTime()){
//          //鎖超時,可以獲取鎖重新設置鎖
//          //計算 newExpireTime = 當前時間+過期超時時間,然后 getset(lockkey, newExpireTime) 會返回當前 lockkey的值currentExpireTime
//          long newExpireTime = new Date().getTime() + expireTime;
//          String currentExpireTime = jedis.getSet(lockKey, newExpireTime + "");
//          if(currentExpireTime.equals(oldExpireTime)){
//            return true;
//          }
//        }
//        return false;
//      }
    }finally {
      returnResource(jedis);
    }
  }
 
  /**
   * 釋放分布式鎖
   * @param jedis Redis客戶端
   * @param lockKey 鎖
   * @return 是否釋放成功
   */
  public static boolean closeLock(Jedis jedis, String lockKey, String lockValue) {
    log.info("----釋放Jedis分布式鎖----lockKey:{}, lockValue:{}", lockKey, lockValue);
    try {
      String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
      Object result = jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(lockValue));
      if (RELEASE_SUCCESS.equals(result)) {
        return true;
      }
      return false;
    }finally {
      returnResource(jedis);
    }
  }
 
  /**
   * 關閉資源
   * @param jedis
   */
  public static void returnResource(final Jedis jedis){
    if(null != jedis){
      jedis.close();
    }
  }
}

關于怎么在SpringBoot中利用redis實現分布式鎖就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

灵川县| 鹿邑县| 资溪县| 长沙县| 广平县| 花莲县| 鄄城县| 会理县| 文安县| 林州市| 资源县| 丁青县| 芮城县| 苏尼特左旗| 东乌珠穆沁旗| 临沧市| 洱源县| 鄯善县| 金塔县| 临夏县| 天等县| 临沭县| 河曲县| 家居| 师宗县| 京山县| 哈尔滨市| 沙湾县| 临沧市| 赣榆县| 同德县| 永康市| 贞丰县| 馆陶县| 隆子县| 股票| 滨州市| 屯昌县| 弋阳县| 宁陕县| 本溪|