当前位置:网站首页>Redis implementation of distributed lock solution
Redis implementation of distributed lock solution
2022-07-26 10:36:00 【Fan Xuebo】
spring boot edition 2.1.6.RELEASE
The following is the acquisition and release of distributed locks , Member variables :StringRedisTemplate(springboot Integrate redis obtain redis, It can also be injected jedis Realization , The realization idea is consistent , I will attach at the end of the text to get redis The implementation of the ).
Let's take a look at some more redis Basic command : SETNX key value (stringRedisTemplate.opsForValue().setIfAbsent())
If key non-existent , Is set key Corresponding string value. under these circumstances , The order and SET equally . When key Preexisting time , Do nothing .SETNX yes ”SET if Not eXists”. expire KEY seconds (stringRedisTemplate.expire())
Set up key The expiration time of . If key Has expired , Will be automatically deleted . del KEY (stringRedisTemplate.delete())
Delete key
Acquisition and release of distributed locks
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
/**
* @author fanxuebo
* @description Distributed lock
* @company
* @create 2019/1/10 17:48
*/
public class DistributedLock {
private static final Logger LOGGER = LoggerFactory.getLogger(DistributedLock.class);
private StringRedisTemplate stringRedisTemplate;
public DistributedLock(StringRedisTemplate stringRedisTemplate) {
this.stringRedisTemplate = stringRedisTemplate;
}
/**
* @Author fanxuebo
* @Date 2019/1/11 10:10
* @Description Get the lock , Name of lock , Gets the locktimeout time , Timeout for releasing the lock
**/
public String lockWithTimeout(String lockName, long timeout) {
String retIdentifier = null;
try {
String identifier = UUID.randomUUID().toString();// Randomly generate one value
String lockKey = "lock:" + lockName;// Lock name , namely key value
int lockExpire = (int) (timeout / 1000);// Timeout time , After locking, the lock will be released automatically
while (true) {
if (stringRedisTemplate.opsForValue().setIfAbsent(lockKey, identifier)) {
LOGGER.info("{}: Get lock lockKey:{}", Thread.currentThread().getName(), lockKey);
stringRedisTemplate.expire(lockKey, lockExpire, TimeUnit.SECONDS);
retIdentifier = identifier;// return value value , Used to release lock time confirmation
break;
}
// return -1 representative key No timeout set , by key Set a timeout
if (stringRedisTemplate.getExpire(lockKey) == -1L) {
stringRedisTemplate.expire(lockKey, lockExpire, TimeUnit.SECONDS);
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
} catch (Exception e) {
e.printStackTrace();
LOGGER.error(" Get lock exception :[{}]", e.getStackTrace()[0]);
}
return retIdentifier;
}
/**
* @Author fanxuebo
* @Date 2019/1/11 10:09
* @Description Release the lock
**/
public boolean releaseLock(String lockName, String identifier) {
String lockKey = "lock:" + lockName;
boolean retFlag = false;
try {
while (true) {
stringRedisTemplate.watch(lockKey);// monitor lock, Get ready to start
// Go back through the value Value to determine whether the lock should be , If it's time to lock , Delete , Release the lock
if (identifier.equals(stringRedisTemplate.opsForValue().get(lockKey))) {
LOGGER.info("{}: Delete lock lockKey:{}", Thread.currentThread().getName(), lockKey);
stringRedisTemplate.delete(lockKey);
retFlag = true;
}
stringRedisTemplate.unwatch();
break;
}
} catch (Exception e) {
e.printStackTrace();
LOGGER.error(" Abnormal release of lock :[{}]", e.getStackTrace()[0]);
}
return retFlag;
}
}In the code block that needs to be locked, just do the following :
DistributedLock distributedLock = new DistributedLock(stringRedisTemplate);
String lockName = XXX;
String identifier = null;
try {
identifier = distributedLock.lockWithTimeout(lockName, 3000);
// Need the code to control the transaction
distributedLock.releaseLock(lockName, identifier);
} catch (Exception e) {
distributedLock.releaseLock(lockName, identifier);
}The lock acquisition method can be improved , Pass in the time to acquire the lock , Get , If no ID is obtained, the returned ID is NULL.
long end = System.currentTimeMillis() + acquireTimeout;
while (System.currentTimeMillis() < end) {}DistributedLock distributedLock = new DistributedLock(stringRedisTemplate);
String lockName = XXX;
String identifier = null;
try {
identifier = distributedLock.lockWithTimeout(lockName, 3000);
if (StringUtils.isBlank(identifier)) {
// Processing of lock acquisition waiting timeout
}
// Need the code to control the transaction
distributedLock.releaseLock(lockName, identifier);
} catch (Exception e) {
distributedLock.releaseLock(lockName, identifier);
}
springboot Integrate reids:
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<!-- <version>2.1.6.RELEASE</version> -->
</dependency>import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/**
* @author fanxuebo
* @description redis Configuration class
* @company
* @createDate 2019-11-27 08:46:17 Wednesday
*/
@Configuration
public class RedisConfiguration {
/**
* @Author fanxuebo
* @Date 2019/11/27 9:05
* @Description jdk Sequence mode , To save objects
**/
@Bean
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
return getRedisTemplate(redisTemplate, redisConnectionFactory);
}
/**
* @Author fanxuebo
* @Date 2019/11/27 9:06
* @Description string Sequence mode , Used to store string format
**/
@Bean
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
return (StringRedisTemplate) getRedisTemplate(stringRedisTemplate, redisConnectionFactory);
}
private RedisTemplate getRedisTemplate(RedisTemplate redisTemplate, RedisConnectionFactory redisConnectionFactory) {
redisTemplate.setConnectionFactory(redisConnectionFactory);
// Use Jackson2JsonRedisSerialize Replace default serialization
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
// Set up value The serialization rules and key Serialization rules
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}
The configuration file :
spring:
redis:
database:
host:
port: 6379
password:
timeout: 5000
jedis:
pool:
max-active: 50
max-wait: 5000I hope you will gain something after reading , This article needs to be improved ...
边栏推荐
猜你喜欢

数据分析入门 | kaggle泰坦尼克任务

第8期:云原生—— 大学生职场小白该如何学

我们的Web3创业项目,黄了
![[leetcode每日一题2021/5/8]1723. 完成所有工作的最短时间](/img/e7/a48bb5b8a86cbc4cd5b37bb16661a8.png)
[leetcode每日一题2021/5/8]1723. 完成所有工作的最短时间

干货likeshop外卖点餐系统开源啦100%开源无加密

STM32 Alibaba cloud mqtt esp8266 at command
![[leetcode每日一题2021/8/30]528. 按权重随机选择【中等】](/img/13/c6cb176d7065035f60d55ad20ed1bf.png)
[leetcode每日一题2021/8/30]528. 按权重随机选择【中等】

.NET5WTM(ASP.NET Core) PGSql开箱操作

STM32 阿里云MQTT esp8266 AT命令
![[Halcon vision] Fourier transform of image](/img/9c/d6ed4ab3e40f706f3b5b8b5cc51db9.png)
[Halcon vision] Fourier transform of image
随机推荐
404页面和路由钩子
Navicat15连接本地虚拟机的Mysql(Centos7)
少了个分号
【机器学习小记】【人脸识别】deeplearning.ai course4 4th week programming
父类对子类的引用(父类引用指向子类对象)
Function template parameters (where are the function parameters)
A semicolon is missing
datav漂亮数据屏制作体验
cavans实现静态滚动弹幕
.NET5WTM(ASP.NET Core) PGSql开箱操作
.net operation redis sorted set ordered set
[Halcon vision] array
Our Web3 entrepreneurship project is yellow
11 在 operator= 中处理“自我赋值”
Unit test, what is unit test and why is it so difficult to write a single test
2022/07/25------字符串的排列
[leetcode每日一题2021/2/13]448. 找到所有数组中消失的数字
Okaleido生态核心权益OKA,尽在聚变Mining模式
uniapp使用简单方法signalR(仅用于web调试,无法打包app)
Database functions