超卖问题解决方案

523 阅读2分钟

超卖问题

前言

先对超卖问题做个一简单的描述:一般电商系统都会遇到的问题,例如秒杀,特价等活动,这类活动都有一个共同点,那就是访问量大,有大量并发请求,然而商品的库存有限,如果不控制购买的数量,就会造成超卖现象。

问题描述1

image-20230822202928298.png

存在问题: 假如现在某个商品库存为1,此时有两个用户同时发起请求购买该商品,其中一个请求先执行3,更新了数据库的库存为0,但还未执行到4。而另一个请求已经执行到了2,查询得出库存为1,于是继续执行3,结果就会发现卖出了两份,而数据库中库存已经没有了,就导致了超卖。

解决方法: 用锁将2,3,4步给锁住,等第一个请求将2,3,4步都执行完之后,第二个请求才能进行2,此时第二个请求查询的库存就是已经更新了的库存

问题描述2

假如现在又增加了一台服务器

image-20230822204059204.png 存在问题: 假设此时两个用户的请求同时到来,但是落在了不同的机器上,那么这两个请求是可以同时执行了,还是会出现库存超卖的问题。为什么呢?因为上图中的两个A系统,运行在两个不同的JVM里面,他们加的锁只对属于自己JVM里面的线程有效,对于其他JVM的线程是无效的。因此,这里的问题是Java提供的原生锁机制在多机部署场景下失效了这是因为两台机器加的锁不是同一个锁(两个锁在不同的JVM里面)。

问题解决: 要保证两台机器加的锁是同一个锁,此时就该使用分布式锁,分布式锁的思路是:在整个系统提供一个全局、唯一的获取锁的“东西”,然后每个系统在需要加锁时,都去问这个“东西”拿到一把锁,这样不同的系统拿到的就可以认为是同一把锁。至于这个“东西”,可以是Redis、Zookeeper,也可以是数据库。