当前位置:网站首页>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 ...
边栏推荐
- .net operation redis set unordered collection
- Introduction to data analysis | kaggle Titanic mission (I) - > data loading and preliminary observation
- Mlx90640 infrared thermal imager temperature sensor module development notes (6)
- centos8(liunx)部署WTM(ASP.NET 5)使用pgsql
- 第6期:大学生应该选择哪种主流编程语言
- Google与Pixar开发Draco支持USD格式 加速3D对象传输&lt;转发&gt;
- [Halcon vision] threshold segmentation
- Kaptcha image verification code integration
- json-c库的简单使用——将json文件转换为struct.
- Okaleido生态核心权益OKA,尽在聚变Mining模式
猜你喜欢

第6期:大学生应该选择哪种主流编程语言

议程速递 | 7月27日分论坛议程一览

【机器学习小记】【人脸识别】deeplearning.ai course4 4th week programming
![[Halcon vision] threshold segmentation](/img/1c/e2463a796f99804a55680b69e714a6.png)
[Halcon vision] threshold segmentation

Introduction to data analysis | kaggle Titanic mission (I) - > data loading and preliminary observation

The difference between equals and = =

Dry goods likeshop takeout order system is open source, 100% open source, no encryption

404页面和路由钩子

Write to esp8266 burning brush firmware

Uniapp uses the simple method signalr (only for web debugging, cannot package apps)
随机推荐
Wechat official account release reminder (wechat official account template message interface)
Inheritance method of simplified constructor (I) - combined inheritance
[gossip] error loading psychopg2 module: no module named psychopg2
The problem of large fluctuation of hx711 data
头歌 Phoenix 入门(第1关:Phoenix 安装、第2关:Phoenix 基础语法)
PLC overview
Function templates and non template functions with the same name cannot be overloaded (definition of overloads)
Listening freely, the next stop of online text traffic competition?
Function template parameters (where are the function parameters)
议程速递 | 7月27日分论坛议程一览
分布式锁解决方案之Redis实现
13 以对象管理资源
2022pta平时训练题(1~10题字符串处理问题)
[Halcon vision] Fourier transform of image
PTA class a 1002
[leetcode每日一题2021/2/14]765. 情侣牵手
关于函数模板描述错误的是(链接格式错误怎么解决)
卸载魅族应用商店
Tradingview 使用教程
Navicat15连接本地虚拟机的Mysql(Centos7)