REDIS

Redis实战11-实现优惠券秒杀下单

本篇,咱们来实现优惠券秒杀下单功能。通过本篇学习,我们将会有如下收获:1:优惠券领券业务逻辑;2:分析在高并发情况下,出现超卖问题产生的原因;3:解决超卖问题两种方案:版本号法及CAS法4:乐观锁弊端改进方案;本文涉及内容比较多,篇幅会比较长,同时有大量截图。希望大家能耐心看完。好了,话不对说,咱们开始gogogo~一:基本的秒杀实现下单时候需要判断:1:秒杀是否开始或结束,如果尚未开始或者已经结

本篇,咱们来实现优惠券秒杀下单功能。通过本篇学习,我们将会有如下收获:

1:优惠券领券业务逻辑;

2:分析在高并发情况下,出现超卖问题产生的原因;

3:解决超卖问题两种方案:版本号法及CAS法

4:乐观锁弊端改进方案;

本文涉及内容比较多,篇幅会比较长,同时有大量截图。希望大家能耐心看完。好了,话不对说,咱们开始go go go~

一:基本的秒杀实现

99a822115ff8de14cd86ae9ff306ee30.png

下单时候需要判断:

1:秒杀是否开始或结束,如果尚未开始或者已经结束则无法下单;

2:库存是否充足,不充足无法下单

业务:

34fcbd573f67cb5b1d71da51097f3115.png

根据上图逻辑,我们可以得到代码相关逻辑:

1:查下优惠券、

2:判断是否秒杀开始;

3:判断秒杀是否结束;

4:判断库存是否充足;

5:扣减库存;

6:创建订单;

相关代码如下:

cf751ab7b9fa4fdd4126f7d66cdc4c02.png

二:分析上面代码是否存在问题

我们使用JMeter模拟200个用户去秒杀抢优惠券。运行结果:

543b1a6921984d169f3fd81fbefbbe46.png

异常是45.5%。这个不对啊,按照我们预期的应该是50%的用户失败才对。这45.5%,说明优惠券超卖出了9个。是吗?我们来查查优惠券表:

dbad2e6bf581383356d758c844bd5f30.png

库存为-9.再来查询订单表:发现订单是109条。在高并发的情况下,还真的是超卖出了9个呢。

来分析为什么会出现这种情况呢?

来看看代码,扣减库存的相关代码:

ddd63135a8a2138181435e5815bbb841.png

我们来分享下扣除库存流程:

两个线程来抢,假设当前就库存就剩下一个了。线程1和线程2来抢这个库存。流程如下:

475ba5e735fc86f1bfa1a2ad46136e47.png

在高并发的情况下,线程谁先执行,还真不好说。在高并发情况下,可能执行的顺序就如下图:

23f3d93354ef4ea0e3476360f6bc5f87.png

超卖问题分析:

T1的时候,线程1执行从数据库查询操作,查询结果为1;然后CPU让出,线程2来执行,在T2时候,线程2也去执行数据库查询操作,查询结果也是1.然后线程2,让出CPU,T3时候,线程1得到了CPU执行权,执行扣除库存操作。T4时候线程得到了CPU执行权,同样执行扣除库存操作。当两个线程都执行完成后,数据库中的库存就成了-1了。

这只是有2个线程,当高并发的时候,有多个线程来查询库存,扣除库存。如果出现了上面情况,就会出现超卖情况。

超卖问题场景的解决方案

超

原创不易,完成人机校验,阅读全文

相关推荐