当前位置:网站首页>Several implementation methods of redis distributed lock
Several implementation methods of redis distributed lock
2022-06-09 05:30:00 【CodingAnHour】
1、Jedis
/** * Acquire distributed lock , Lock ID returned successfully * @param lockName Compete to acquire locks key * @param acquireTimeoutInMS Gets the locktimeout time * @param lockTimeOut The timeout of the lock ( second ) * @return Lock logo */
public String acquireLockWithTimeout(String lockName, long acquireTimeoutInMS, int lockTimeOut) {
Jedis conn = null;
// Lock logo
String retIdentifier = null;
try {
conn = jedisPool.getResource();
// Value of lock
String identifier = UUID.randomUUID().toString();
// The lock key
String lockKey = "lock:" + lockName;
// Gets the locktimeout time
long end = System.currentTimeMillis() + acquireTimeoutInMS;
while (System.currentTimeMillis() < end) {
// key In the presence of , Do not operate , return 0, A situation that does not exist set identifier return 1
if (conn.setnx(lockKey, identifier) == 1) {
// Set up lockKey Time to live , When lockKey expires , It will be automatically deleted
conn.expire(lockKey, lockTimeOut);
// Returns the lock identifier
retIdentifier = identifier;
// Get the lock and jump out of the loop , return
break;
}
try {
// Rotation sleep 10 millisecond
Thread.sleep(10);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
}
}
} finally {
if (conn != null) {
conn.close();
}
}
return retIdentifier;
}
/** * Acquire distributed lock , If successful, the lock ID will be returned , Failure return null * @param lockName Compete to acquire locks key * @param lockTimeOut The timeout of the lock ( second ) * @return Lock logo */
public String acquireLock(String lockName, int lockTimeOut) {
Jedis conn = null;
// Lock logo
String retIdentifier = null;
try {
conn = jedisPool.getResource();
String identifier = UUID.randomUUID().toString();
String lockKey = "lock:" + lockName;
// key In the presence of , Do not operate , return 0, A situation that does not exist set identifier return 1
if (conn.setnx(lockKey, identifier) == 1) {
// Set up lockKey Time to live , When lockKey expires , It will be automatically deleted
conn.expire(lockKey, lockTimeOut);
// Returns the lock identifier
retIdentifier = identifier;
// Get the lock and jump out of the loop , return
}
} finally {
if (conn != null) {
conn.close();
}
}
return retIdentifier;
}
/** * Release the lock * @param lockName Compete to acquire locks key * @param identifier Release lock identification * @return */
public boolean releaseLock(String lockName, String identifier) {
Jedis conn = null;
// lock key
String lockKey = "lock:" + lockName;
// Return to status
boolean retFlag = false;
try {
conn = jedisPool.getResource();
while (true) {
// monitor lock, If before the transaction is executed ( Or these ) key Altered by other orders , Then the business will be interrupted .
conn.watch(lockKey);
if (identifier.equals(conn.get(lockKey))) {
// Open transaction
Transaction trans = conn.multi();
// Delete key
trans.del(lockKey);
// Execute commands within all transaction blocks EXEC Command atomicity
List<Object> results = trans.exec();
if (results == null) {
continue;
}
retFlag = true;
}
// Cancel WATCH Command to all key Surveillance
conn.unwatch();
break;
}
} finally {
if (conn != null) {
conn.close();
}
}
return retFlag;
}
2、RedisTemplate
/** * Atomic insertion ( Mutually exclusive ), Successfully returns true * @param key * @param value * @param timeout-seconds * @return */
public boolean setNX(String key,String value,int timeout) {
return redisTemplate.opsForValue().setIfAbsent(key, value,timeout,TimeUnit.SECONDS);
}
3、Redission
<!-- Distributed redis lock -->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.6.5</version>
</dependency>
Inject bean, For reference only , The parameters in the environment can be matched more gracefully
@Bean
public RedissonClient redisson(){
// standalone mode
Config config = new Config();
config.useSingleServer().setAddress("redis://127.0.0.1:6380").setDatabase(1);
return Redisson.create(config);
}
java Example
@RequestMapping(value = "/stock")
public String deductStock(){
// Encrypted key
String lockKey = "product:001";
// 1. Get lock object
RLock redissonLock = redisson.getLock(lockKey);
try{
// 2. Lock Equivalent to setIfAbsent, Default key Expiration time 30s
redissonLock.lock();
// from redis Get the value of the current inventory
int stock = Integer.parseInt(redisUtil.get("stock"));
if(stock > 0){
int realStock = stock - 1;
boolean stock1 = redisUtil.set("stock", realStock+"");
System.out.println(" Deduction succeeded , Surplus stock :" + realStock);
}else{
System.out.println(" Deduction failed , Insufficient inventory ");
}
}finally {
// 3. Release the lock
redissonLock.unlock();
}
return"end";
}
Redission The middle lock bottom layer uses lua It is implemented by script
- exists Judge key Whether there is
- When it is judged that there is no such thing as hash How to set key
- Then set the key Add expiration time
- Evoke a scheduled task running in the background , Every time the lock expiration time is set 1/3 Time to execute once , Delay the lock


The same goes for releasing the lock lua How to script 
4、 Distributed locking techniques
scene 1:
- When redis When a single commodity or multiple commodities are snapped up (redis Cluster structure ), Commodity distributed lock definition key=product:001 when , Locks occupy all nodes , If
key=product:001-100:001;key=product:101-200:101To disperse the lock , In this way, locking can make the lock fall on different nodes , Make full use of cluster multi node mode ,Realize the horizontal expansion of the lock , Improve lock performance
边栏推荐
猜你喜欢

queue

Mysql5 available clusters

SET DECIMAL_V2=FALSE及UDF ERROR: Cannot divide decimal by zero及Incompatible return types DECIMAL问题排查

MarathonLb的负载研究

STM32 FreeRTOS task Basics

MRNA factory| quantitative detection of LNP encapsulated RNA content by ribogreen

The 27th issue of product weekly report | members' new interests of black users; CSDN app v5.1.0 release

Interview process and thread

Unbutu 安装FFmpeg的两种方法

Cloud computing technology
随机推荐
Thinking about global exception capture - real global exception capture
Mysql 添加字段或者创建表SQL语句
When classical music meets NFT
Pattern recognition big job PCA & Fisher & KNN & kmeans
Missing digit JS in sword finger 0~n-1
Common interview questions
seaweedfs-client适配高版本的seaweedfs服务
AQS 之 CountdownLatch 源码分析
Kube dns yaml
Summary of Android Engineer interview experience with 5 years' work experience, summary of real interview questions of Ali + Tencent + byte jump
Alibaba cloud AI training camp -sql foundation 2: query and sorting
Windows10 installs both MySQL 5 and MySQL 8
SQL optimization notes - forward
Mysql5.7 dual master and dual slave configuration
Swift 扩展
Rsync synchronous backup
Mysql5.7 one master multi slave configuration
PS how to add white edges to images
Camtasia studio2022 free key serial number installation trial detailed graphic tutorial
The difference between traditional method and lean method