初始第一版代码
背景:Redis中stock字段的value设为300
超卖问题:
多个请求(3个)同时调用这个接口,他们查出的stock都是300,都进行减1操作,实际上需要减3得到297,但都是执行300-1记录stock为299。
解决:使用jdk自带的锁,可以使多个请求排队,实现同一时间单个请求执行锁区间的代码。
架构背景:前端部署在nginx,实现负载均衡。请求实现分发到不同的服务器上。不同服务器,有着各自独立的jvm,jdk。
像synchronize,retreentlock是进程级别的,只能在当前进程内部有效。
问题:jvm提供的锁,集群情况下,这个是不能控制并发超卖问题的。
解决:使用Redis的setnx命令,实现分布式锁。
Redis执行请求命令时,是串行执行的。会进行排队。
setnx:有无存在此key,无则设置vlaue,有则不做操作。锁的效果,去处理并发资源问题。
代码实现:
多个请求同时调用接口,利用Redis接收all,实现一个请求setnx成功--锁住资源(商品),正常执行减商品逻辑,其他请求进行错误提示返回。
问题:执行后续减库存的请求,在后续逻辑都会有出现异常的可能,一旦过程出现异常,则导致后续无法执行释放锁,锁得不到释放,后续出现的请求无法正常拿到商品资源锁。
解决:加try,finally,释放锁放入finally。无论抛什么异常,都必须把锁释放掉。
问题:执行到一半,服务器宕机,不能执行到释放锁。
解决:加过期时间。
问题:执行完锁资源,服务器宕机了,锁得不到释放。
解决:将锁资源、设置过期时间设为原子操作,这样无论发生什么,只要设置锁,就会有锁释放的时候。
标签:释放,请求,300,Redis,服务器,执行,分布式 From: https://www.cnblogs.com/fengok/p/17965336