版本三
针对前面版本二还有一点需要优化,就是加锁和解锁必须是同一个客户端,所以在加锁时可以设置当前线程id,在释放锁时判断是否为当前线程加的锁,如果是再释放锁即可。
Java程序:
@GetMapping("/stock")
public String stock() {
try {
String threadId = Thread.currentThread().getId()+"";
//尝试加锁
Boolean locked = redisTemplate.opsForValue().setIfAbsent("mylock",threadId,5000,TimeUnit.MILLISECONDS);
if(locked){//加锁成功
int stock = Integer.parseInt(redisTemplate.opsForValue().get("stock"));
if(stock > 0){
stock --;
redisTemplate.opsForValue().set("stock",stock+"");
System.out.println("库存扣减成功,剩余库存:" + stock);
}else {
System.out.println("库存不足!!!");
}
String myValue = redisTemplate.opsForValue().get("mylock");
if(threadId.equals(myValue)){
//释放锁
redisTemplate.delete("mylock");
}
}else{
System.out.println("没有获取锁,不能执行减库存操作!!!");
}
}catch (Exception ex){
System.out.println("出现异常!!!");
}
return "OK";
}