什么是分布式锁
分布式锁其实就是:控制分布式系统有序的去对共享资源进⾏操作,通过互斥来保持⼀致性。
三个服务并发操作数据库共享资源
Redis分布式锁的实现核⼼思路
1、实现分布式锁的思路就是利⽤ Redis 的两个命令:setnx 和 setex,修改数据前使⽤ setnx 命令对操作加锁,防⽌其他系统执⾏相同操作,使⽤ setex 命令设置锁超时时间(这⼀步的⽬的是防⽌系统突然挂掉,没有解锁),在操作结束后,进⾏解锁
@Resource
private StringRedisTemplate stringRedisTemplate; 16
@RequestMapping("/deduct_stock")
public String deductStock(){
String lockKey = "product001";
try{
for (;;){
//使⽤ setnx 命令对操作加锁
Boolean result = stringRedisTemplate.opsForValue().setIfAb sent(lockKey, "redis_lock");
//使⽤ setex 命令设置锁超时时间
stringRedisTemplate.expire(lockKey, 10, TimeUnit.SECONDS);
if(result){
break;
}
}
//减库存
synchronized (this) {
int stock = Integer.parseInt(stringRedisTemplate.opsForVal ue().get("stock"));
if (stock > 0) {
int realStock = stock - 1;
stringRedisTemplate.opsForValue().set("stock", realSto ck + "");
System.out.println("真实库存为 " + realStock);
} else {
System.out.println("库存不⾜");
}
}
return "ok";
2、把加锁操作和设置锁超时时间做成⼀个原⼦操作,防⽌程序挂掉导致的死锁问题
@Resource
private StringRedisTemplate stringRedisTemplate; 16
@RequestMapping("/deduct_stock")
public String deductStock(){
String lockKey = "product001";
try{
//加锁操作和设置锁超时时间做成⼀个原⼦操作
for (;;){
Boolean result = stringRedisTemplate.opsForValue().setIfAb sent(lockKey, "redis_lock", 30, TimeUnit.SECONDS);
if(result){
break;
}
}
//减库存
synchronized (this) {
int stock = Integer.parseInt(stringRedisTemplate.opsForVal ue().get("stock"));
if (stock > 0) {
int realStock = stock - 1;
stringRedisTemplate.opsForValue().set("stock", realSto ck + "");
System.out.println("真实库存为 " + realStock);
} else {
System.out.println("库存不⾜");
}
}
return "ok";
}finally {
/释放锁
stringRedisTemplate.delete(lockKey);
}
- 同时还要考虑到锁过期,所以需要额外的⼀个看⻔狗定时任务来监听锁是否需要续期