我的博客大纲
我的后端学习大纲
1、setnx命令:
2、逻辑梳理:
- 1.借助于redis中的命令
setnx(key, value)
,key不存在就新增,存在就什么都不做。同时有多个客户端发送setnx命令,只有一个客户端可以成功,返回1(true);其他的客户端返回0(false)。
1.多个客户端同时获取锁(setnx)
2.获取成功,执行业务逻辑,执行完成释放锁(del)
3.其他客户端等待重试
3、编码实现:
- 1.改造
StockService
方法:
@Service
public class StockService {
@Autowired
private StringRedisTemplate redisTemplate;
public void deduct() {
// 加锁setnx
Boolean lock = this.redisTemplate.opsForValue().setIfAbsent("lock", "111");
// 如果没有抢到锁,那么就进行重试:实现递归调用
if (!lock){
try {
Thread.sleep(50);
this.deduct();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
try {
// 1. 查询库存信息
String stock = redisTemplate.opsForValue().get("stock").toString();
// 2. 判断库存是否充足
if (stock != null && stock.length() != 0) {
Integer st = Integer.valueOf(stock);
if (st > 0) {
// 3.扣减库存
redisTemplate.opsForValue().set("stock", String.valueOf(--st));
}
}
} finally {
// 解锁
this.redisTemplate.delete("lock");
}
}
}
}
- 2.其中,加锁也可以使用循环:
// 加锁,获取锁失败重试
while (!this.redisTemplate.opsForValue().setIfAbsent("lock", "111")){
try {
Thread.sleep(40);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
- 3.解锁:
// 释放锁
this.redisTemplate.delete("lock");
4、使用Jmeter压力测试