lua操作redis
参考:https://blog.csdn.net/weixin_54721305/article/details/125648123
实现分布式锁#
依赖#
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
</dependencies>
application.properties#
# 指定端口号
server.port=8199
# 连接redis
spring.redis.host=192.168.171.138
spring.redis.port=6379
config#
/**
* @Author 嘉宾
* @Data 2022/7/6 20:37
* @Version 1.0
* @Description 用于声明lua
*/
@Configuration
public class LuaRedisConfig {
/**
* 分布式锁脚本
* @return
*/
@Bean
public DefaultRedisScript<Long> lockRedisScript() {
// 定义DefaultRedisScript
DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>();
// 指定lua脚本路径
redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("script/lock.lua")));
// 设置返回类型
redisScript.setResultType(Long.class);
return redisScript; // 返回lua脚本内容
}
}
script#
在resources目录下创建目录script目录在其目录下创建Lua脚本文件
local lockUUID = KEYS[1] -- 锁中的uuid值
local uuid = ARGV[1] -- 用户的uuid值
-- 判断锁中的uuid是否与用户的uuid相等
if redis.call('get',lockUUID) == uuid then
return redis.call('del',lockUUID) -- 相等的话就释放锁
else -- 未获得锁
return 0 -- 返回0
end
controller#
/**
* @Author 嘉宾
* @Data 2022/7/6 20:39
* @Version 1.0
* @Description
*/
@RestController
@RequestMapping("/lua")
public class TestController {
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Resource
private DefaultRedisScript<Boolean> lockRedisScript; // 分布式锁脚本
/**
* 计数
* @return
*/
@GetMapping("/getLock")
public String getLock(){
// 生成UUID
String uuid = UUID.randomUUID().toString();
// 1、获取锁:true得到锁,false未得到
Boolean redisLock = stringRedisTemplate.opsForValue().setIfAbsent("lock_redis", uuid,3, TimeUnit.SECONDS);
// 判断是否得到锁
if(redisLock){
// ...自己的业务
String value = stringRedisTemplate.opsForValue().get("num");
if(StringUtils.isEmpty(value)){
stringRedisTemplate.opsForValue().set("num","1");
}
int num = Integer.parseInt(value + "") + 1;
stringRedisTemplate.opsForValue().set("num",num+"");
// 获取锁中的内容
String lockUUID = stringRedisTemplate.opsForValue().get("lock_redis");
// 使用Lua脚本比较
// 指定参数
List<String> keys = Arrays.asList(lockUUID);
stringRedisTemplate.execute(lockRedisScript,keys,uuid);
return "success"+num;
}else{
// // 每隔0.1秒再获取一次
// try {
// Thread.sleep(100);
// this.getLock();
// }catch (InterruptedException e){
// e.printStackTrace();
// }
return "miss";
}
}
}
作者:hasome
出处:https://www.cnblogs.com/hasome/p/17702037.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)