参考: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";
}
}
}
标签:return,uuid,--,redis,lua,操作,stringRedisTemplate
From: https://www.cnblogs.com/hasome/p/17702037.html