(线程安全问题)
使用redis中的setIfAbsent(setnx命令)实现分布式锁
1.只加锁,未释放锁。
线程拿到锁执行业务后执行释放锁操作。
2.如果一个线程拿到锁后宕机了,锁就释放不了,其他线程拿不到锁。
在setIfAbsent()的中包含Timeout参数,可以给当前锁设置过期时间。
3.线程拿了别的线程的锁释放了。(当前1号线程加锁后由于性能原因卡住了,在设定的Timeout过期后自动释放锁,2号线程拿到锁开始执行业务,此时1号不卡了,执行业务后会释放锁,释放的就是2号线程的锁)
在获取到锁的时候,给锁分配一个id。(拿锁之前可以生成一个UUID为threadId,将其放入锁参数中,在进行释放锁的操作之前先获取锁里面的threadId,跟拿锁之前的threadId进行校验,相同则释放锁。)
4.redis的redisson解决方案
https://www.cnblogs.com/jackson0714/p/redisson.html
https://juejin.cn/post/6961380552519712798
Spring Boot 整合 Redisson 有两种方案:
1. 程序化配置。
2. 文件方式配置。
程序化配置:
4.1引入 Maven 依赖
在当前微服务的 pom.xml 引入 redisson的 maven 依赖。
org.redisson
redisson
3.14.0
4.2自定义配置
@SpringBootApplication
public class RedisLockApplication {
public static void main(String[] args) {
SpringApplication.run(RedisLockApplication.class, args);
}
@Bean
public RedissonClient redisson(){
// 1.创建配置
Config config = new Config();
// 集群模式
// config.useClusterServers().addNodeAddress("127.0.0.1:7004", "127.0.0.1:7001");
// 2.根据 Config 创建出 RedissonClient 示例。
config.useSingleServer().setAddress("redis://127.0.0.1:6379");
return Redisson.create(config);
}
}
4.3测试配置类



