SpringBoot集成redis實(shí)現(xiàn)分布式鎖的示例代碼
1、準(zhǔn)備
使用redis實(shí)現(xiàn)分布式鎖,需要用的setnx(),所以需要集成Jedis
需要引入jar,jar最好和redis的jar版本對(duì)應(yīng)上,不然會(huì)出現(xiàn)版本沖突,使用的時(shí)候會(huì)報(bào)異常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、配置參數(shù)
spring:
redis:
host: localhost
port: 6379
password: root
timeout: 5000
# Redis數(shù)據(jù)庫(kù)索引(默認(rèn)為0)
database: 0
# 連接池最大連接數(shù)(使用負(fù)值表示沒有限制)
jedis:
pool:
# 連接池最大連接數(shù)(使用負(fù)值表示沒有限制)
max-active: 8
# 連接池最大阻塞等待時(shí)間(使用負(fù)值表示沒有限制)
max-wait: -1
# 連接池中的最大空閑連接
max-idle: 8
# 連接池中的最小空閑連接
min-idle: 0
# 獲取連接時(shí)檢測(cè)是否可用
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配置項(xiàng)
* @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("=====創(chuàng)建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 超期時(shí)間(秒)
* @return 是否獲取成功
*/
public static boolean tryGetLock(Jedis jedis, String lockKey, String lockValue, int expireTime) {
log.info("----獲取Jedis分布式鎖----lockKey:{}", lockKey);
try {
//方案一,具有原子性,并且可以設(shè)置過(guò)期時(shí)間,避免拿到鎖后,業(yè)務(wù)代碼出現(xiàn)異常,無(wú)法釋放鎖
String result = jedis.set(lockKey, lockValue, new SetParams().nx().ex(expireTime));
if (LOCK_SUCCESS.equals(result)) {
return true;
}
return false;
//方案二,setnx()具有原子性,但是有后續(xù)判斷,整體不具有原子性,不能設(shè)置過(guò)期時(shí)間
// //setnx(lockkey, 當(dāng)前時(shí)間+過(guò)期超時(shí)時(shí)間),如果返回 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()){
// //鎖超時(shí),可以獲取鎖重新設(shè)置鎖
// //計(jì)算 newExpireTime = 當(dāng)前時(shí)間+過(guò)期超時(shí)時(shí)間,然后 getset(lockkey, newExpireTime) 會(huì)返回當(dāng)前 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);
}
}
/**
* 關(guān)閉資源
* @param jedis
*/
public static void returnResource(final Jedis jedis){
if(null != jedis){
jedis.close();
}
}
}
到此這篇關(guān)于SpringBoot集成redis實(shí)現(xiàn)分布式鎖的示例代碼的文章就介紹到這了,更多相關(guān)SpringBoot redis分布式鎖內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 關(guān)于SpringBoot 使用 Redis 分布式鎖解決并發(fā)問題
- SpringBoot整合Redisson實(shí)現(xiàn)分布式鎖
- Springboot整合Redis實(shí)現(xiàn)超賣問題還原和流程分析(分布式鎖)
- springboot 集成redission 以及分布式鎖的使用詳解
- SpringBoot之使用Redis實(shí)現(xiàn)分布式鎖(秒殺系統(tǒng))
- Redis分布式鎖升級(jí)版RedLock及SpringBoot實(shí)現(xiàn)方法
- 基于springboot實(shí)現(xiàn)redis分布式鎖的方法
- SpringBoot3+Redis實(shí)現(xiàn)分布式鎖的配置方法
相關(guān)文章
詳解在springboot中使用Mybatis Generator的兩種方式
這篇文章主要介紹了詳解在springboot中使用Mybatis Generator的兩種方式,本文將介紹到在springboot的項(xiàng)目中如何去配置和使用MBG以及MBG生成代碼的兩種方式,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2018-11-11
java實(shí)現(xiàn)圖片上傳至本地實(shí)例詳解
我們給大家分享了關(guān)于java實(shí)現(xiàn)圖片上傳至本地的實(shí)例以及相關(guān)代碼,有需要的朋友參考下。2018-08-08
jeefast和Mybatis實(shí)現(xiàn)三級(jí)聯(lián)動(dòng)的示例代碼
這篇文章主要介紹了jeefast和Mybatis實(shí)現(xiàn)三級(jí)聯(lián)動(dòng)的示例代碼,代碼簡(jiǎn)單易懂,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10
Spring Security 和Apache Shiro你需要具備哪些條件
這篇文章主要介紹了Spring Security 和Apache Shiro你需要具備哪些條件,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07
spring boot 配置Filter過(guò)濾器的方法
本篇文章主要介紹了spring boot 配置Filter過(guò)濾器的方法,實(shí)例分析了spring boot 配置Filter過(guò)濾器的技巧,有興趣的可以了解一下。2017-03-03
Spring Cloud Feign請(qǐng)求添加headers的實(shí)現(xiàn)方式
這篇文章主要介紹了Spring Cloud Feign請(qǐng)求添加headers的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04
Spring?Boot整合郵箱發(fā)送郵件實(shí)例
大家好,本篇文章主要講的是Spring?Boot整合郵箱發(fā)送郵件實(shí)例,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下2022-02-02

