00:00
接下来呢,我们在浏览器中来去访问一下,我们来去刷新,已经访问成功。此时来看我们的数据库啊,已经减为4999件了。那我再来去访问几次呢?来刷新刷新刷新,我又刷新了三次。此时数据库呀,应该又减了三件库存。那么此时呢,由于咱是单用户串意中访问,所以呢,每访问一次它就会减一。那么在实际开发中,我们的库存可能是有多用户并发访问的啊。比如咱重新的改回5000件。那么咱用什么东西来模拟多用户闭环访问呢?我们可以想到解密的工具了。好,把这个呢,咱给它清空掉,清空掉之后呢,我们来去运行压力测试,那么此时咱5000个请求瞬间就访问完了。喷吐量呢是2000多。然后错误率呢,是0%,也就是说5000个请求全部都成功了。那都成功的情况下。
01:01
咱应该减为零才可以,库存数量每个请求减一啊,那么事实是不是这样的呢?可以刷新还剩4789页。那说呢,那说明安全性出现了问题,已经出现了并发性的问题。那我们啊,怎么解决这个问题呢。咱们就可以去加锁朋友们啊,那么加锁之前我们先去分析一下为什么这样的一个值。这它应该是一个范围啊,一个范围内的随机值应该是一个零到4950之间的一个随机值。好,我们来分析一下为什么。这是因为啊,我们每次发送100个请求。然后呢,发送了50次。那就可能会出现这样两个极限情况啊,第一种极限情况,咱们所有请求都没有并发。哎,都完美错开了,都完美错开了。那都完美错开的情况下。
02:00
那么刚好呢,就把库存减了零了,所以呢,一个基值是零。OK,另外一个极限值多少呢?是4950的这么一个极限值。那比如说呢,我100个请求,每一次是100个请求,这100个请求就完全并发了啊,同时执行了咱们的第一行代码,可以查询库存。此时查询的库存数量,那第一次啊,第一第一批请求是100个对吧,那么查询的库存数量呢,都是5000啊。都是5000。然后呢,一起进入第二行,那第二行的代码,哎,它都符合库存数量呢大于零,库存呢不为空,库存数量大于零。让一起呢?进入第三行代码,他们都去执行stock,点上set count来预更新库存数量了。在原来5000件的基础上进行减一。那么设置100次啊,这这这100个请求,每个请求都把自己的库存数量更新为多少呢?更新为原来数量的基础上减一。
03:04
那原来数量不是5000嘛,都是5000个,那于是呢,都更新为4999。啊,都减一。那么于是呢,再去更新100字到数据库。那这100个请求呢,全部去执行这行代码。最终把数据库里面的数量都更新为4999了,更新了100次,都是4999。那么第一批就这样子,那第二批呢,它读取出来是4999。100个请求读起来都都是4999哈。那么然后呢,我们都去判断啊,依然可以成立这这句话,那于是呢,走到下面这一行代码。那么下面这行代码呢,啊又去减一啊四啊100个请求都去减一,对四千九百九九都减一,都减为四千八啊998件,那最终呢,把4998件设置到数据库,设置100次。
04:02
那最终呢啊,100个请求只减了一个库存啊。那么就会出现超卖现象啊,以此类推啊,它减50次嘛,咱是50P啊。所以呢,极限值呢,应该是零到4950之间的一个随机值啊。OK,那么并发性的问题呢,非常严重。那咋办呢?我们首先肯定选择了GM锁呀,那于是呢,咱把这个锁呢给它打开,打开之后呢,我们再来去重新启动我们的服务。那么咱们来看最终效果怎么样?已经启动成功了,对吧?啊启动成功了,那我们在浏览器中呢,去访问一下刷新,此时我们的库存呢,应该又减了一件,还剩4788件啊,没啥问题。那么接下来呢,我们给它改回5000件库存啊,改好之后呢,我们还是使用解密来做压力测试。那么在这里呢,把这个报表呀,给它清空掉,我们来去运行。
05:04
好5000个请求呢,此时呢,稍微慢了一点,那吞吐量呢,还剩500多个吞吐量。那错误率呢,应该是零号。OK,那么来看,5000个请求已经发送完了。错误率呢是零,吞吐量呢是500多。那么来看数据库里面的最终库存数量,哎,零件。来解决了我们的超脉炎药。啊,那么一说咱在MYSQ场景下,我们依然可以使用JVM锁来解决这个超卖问题哈,啊,第一种解决方案使用JVM本地符,其实不仅仅是咱们的lock可以解决,其实我们使用S也可以去解决啊,比如说呢,我把这个地方呢的注释调我不使用这个lock了,我它改成synchronized。他改成这个玩意儿。改好之后呢,我们现在再来去重新启动一下。
06:01
重新启动,然后呢,我们把这个库存数量啊,改为5000件库存啊来保存。好,启动已经启动好了,那库存已经改好了,那我使用压力测试工具A压一下呢。好,把这个呢给它清空掉,我们来去运行压力测试。那么这个性能啊,其实是差不多的啊,依然是500多的这种并发量啊吞吐量,然后5000个请求呢,都发送完了,错误率呢是0%。来看数据库。啊,此时呢,库存余量依然是零,所以呢,即便本利锁呀,诶好像可以解决。
我来说两句