当前位置:网站首页>Redis distributed lock + Lua atomic operation
Redis distributed lock + Lua atomic operation
2022-07-26 22:12:00 【weixin_ thirty-nine million five hundred and five thousand and 】
package com.example.demo.redis;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.exceptions.JedisNoScriptException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class RedisLockUtil {
// Distributed lock related fields
private static final String LOCK_SUCCESS = "OK";
private static final String SET_IF_NOT_EXIST = "NX";
private static final String SET_WITH_EXPIRE_TIME = "PX";
private static final Long RELEASE_SUCCESS = 1L;
private static final Long UNLOCK_SUCCESS_CODE = 1L;
private volatile String unlockSha1 = "";
private static final Logger logger = LoggerFactory.getLogger(RedisLockUtil.class);
/** * adopt lua Script release lock , To achieve the atomic operation of releasing the lock * Judge whether the lock value is held by the current thread , Unlock if yes , If not, unlocking fails */
String UNLOCK_LUA = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
@Autowired
private JedisCluster jedisCluster;
/** * according to loopTryTime Loop retry * @param lockKey lock key * @param lockVal Lock value , Used for unlocking verification * @param expiryTime Lock expiration time * @param loopTryTime When get fails , The length of time to cycle and retry to acquire the lock * @return Whether to obtain the lock */
public boolean tryLock(String lockKey, String lockVal, long expiryTime, long loopTryTime){
Long endTime = System.currentTimeMillis() + loopTryTime;
while (System.currentTimeMillis() < endTime){
if (tryGetDistributedLock(lockKey, lockVal, expiryTime)){
return true;
}
}
return false;
}
/** * Try to get distributed lock * @param lockKey lock * @param requestId The request id * @param expireTime Beyond the time * @return Success or failure */
public Boolean tryGetDistributedLock(String lockKey, String requestId, long expireTime) {
String result = jedisCluster.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);
if (LOCK_SUCCESS.equals(result)) {
return Boolean.TRUE;
}
return Boolean.FALSE;
}
/** * Release distributed lock * @param lockKey lock * @param requestId The request id * @return Whether to release successfully */
public Boolean tryUnLockEval(String lockKey, String requestId) {
Object result = jedisCluster.eval(UNLOCK_LUA, Collections.singletonList(lockKey), Collections.singletonList(requestId));
if (RELEASE_SUCCESS.equals(result)) {
return Boolean.TRUE;
}
return Boolean.FALSE;
}
/** * Release distributed lock , The most likely reason for release failure is that the business execution time is longer than lockKey Expiration time , The expiration time should be adjusted according to the business scenario * @param lockKey lock key * @param lockVal Lock value * @return Whether to release successfully */
public boolean tryUnLockEvalsha(String lockKey, String lockVal){
List<String> keys = new ArrayList<>();
keys.add(lockKey);
List<String> argv = new ArrayList<>();
argv.add(lockVal);
try {
Object result = jedisCluster.evalsha(unlockSha1, keys, argv);
return UNLOCK_SUCCESS_CODE.equals(result);
} catch (JedisNoScriptException e){
// When there is no script cache , Resend cache
logger.info("try to store script......");
storeScript(lockKey);
Object result = jedisCluster.evalsha(unlockSha1, keys, argv);
return UNLOCK_SUCCESS_CODE.equals(result);
} catch (Exception e){
logger.info(e.getMessage());
return false;
}
}
/** * Due to the use redis colony , Therefore, each node needs to cache a copy of script data * @param slotKey Used to locate the corresponding slot Of slotKey */
public void storeScript(String slotKey){
if (StringUtils.isEmpty(unlockSha1) || !jedisCluster.scriptExists(unlockSha1, slotKey)){
//redis Support script caching , Return hash code , Later, it can be used to call scripts
unlockSha1 = jedisCluster.scriptLoad(UNLOCK_LUA, slotKey);
}
}
}
边栏推荐
- Unity installation failed: operation not allowed, MKDIR
- Pytorch--Visdom使用
- Alibaba three sides: how to solve the problems of MQ message loss, duplication and backlog?
- 06 CP command
- 进程的概念和分类
- 想让照片中的云飘起来?视频编辑服务一键动效3步就能实现
- Selenium automated test interview questions family bucket
- 第15章 mysql用户管理
- Let Xiaobai thoroughly understand performance tuning
- [audio and video] ijkplayer player parameter description document
猜你喜欢

matlab 短时自相关实现

Just one dependency to give swagger a new skin, which is simple and cool

Cmake compiling obs-studio-27.2.0

JDBC summary

现货黄金操作指南与建议(上)

Matlab pitch period estimation post-processing

带你搞懂MySQL隔离级别,两个事务同时操作同一行数据会怎样?

Xshell7 personal free download, use

新兴市场潜力无限,ADVANCE.AI风控产品助中国出海企业筑牢安全发展基础

Let Xiaobai thoroughly understand performance tuning
随机推荐
Actual authority comes from information superiority
ansible安装及使用
同花顺手机炒股开户安全吗?怎么办理开户呢
NPM, NPM Chinese documents, NPM learning and using
Difference between D and C
Matlab draws short-term average amplitude spectrum
Go -- go language naming specification
VB.net Chart1的处理
In depth analysis of the source code, why is the string class immutable? (hit me before you understand)
深入源码剖析String类为什么不可变?(还不明白就来打我)
Dream weaving prompt dedecms error:tag disabled:php!
Protobuf之proto基础语法
Altium designer 22 modify the layer properties of the selected component
Unity对资源管理器操作 打开资源管理器选择文件并筛选文件
A friend with a monthly salary of 50000 told me that you were just doing chores
Go ---- variable usage in go language
JWT implements login authentication + token automatic renewal scheme, which is the correct posture!
Get network time by unity
1 - "pytorch deep learning practice" - linear model
Jd.com won the highest award for intelligent science and technology in China! Inventory JD system intelligent technology