springboot整合redisson
1.添加redisson依赖
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>3.16.3</version>
</dependency>
2.配置redissonClient客户端
@Configuration
public class RedissonConfig {
@Bean
public RedissonClient getClient() {
Config config = new Config();
config.useSingleServer().setAddress("redis://192.168.2.25:7011").setDatabase(0);
RedissonClient redisson = Redisson.create(config);
return redisson;
}
}
3.在代码中使用
@RestController
@RequestMapping("/test")
public class TestController {
@Autowired
private RedisTemplate<String, String> redisTemplate;
@Autowired
private RedissonClient redissonClient;
@GetMapping("/test")
public void redissonTest() {
// 获取锁
RLock lock = redissonClient.getLock("astock_num");
try {
// 加锁
lock.lock();
// 从Redis中取出库存
String numOnject = redisTemplate.opsForValue().get("num");
Integer num = Integer.valueOf(numOnject);
if (num > 0) {
// 扣减库存
num -= 1;
redisTemplate.opsForValue().set("num", String.valueOf(num));
System.out.println("扣减库存成功,库存stock=:" + num);
} else {
//没库存
System.out.println("扣减失败,库存不足");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 释放锁
lock.unlock();
}
}
}
4.redisson原理
线程拿到锁,如果加锁失败,就会while循环不停地尝试加锁,直到加锁成功!
加锁成功后会开启一个子线程,给锁续命. 默认10秒续命一次.
关键源码:
redisson在加锁,解锁过程中如果成功,返回值貌似都为null
加锁关键代码( lua脚本,具有原子性)
源码中如果加锁成功,返回值为null
renewExpirationAsync这个方法就是为lock续命的 续命成功返回值应该是null,如果不为null 续命失败.
续命成功则再次开启子线程续命 定时任务每internalLockLeaseTime/3执行一次
续命关键lua脚本
解锁关键代码