商品超卖控制和订单业务高并发优化

一、下单业务流程分析

订单确认 、下订单(锁库存-创建支付宝订单-生成支付二维码)、扫码支付、异步回调-修改订单状态、查看支付订单
下单后减库存,而不是在付款是减库存(以防1000个人准备下单,提示下单成功,但是准备付款的时候却提示因为库存不足而付款失败,用户心态崩了)
下单后不付款咋办?非秒杀商品,下单后不付款那么24h后取消,秒杀商品 10min后取消。
或者我自己觉得可以在支付页面那里加一个倒计时60s的页面,超时不付款就拜拜。。。

二、如何解决超卖

超卖:订单数量多于商品真实库存数
怎么解决:

1、悲观锁:事务之内,加上行锁 仅innodb支持

Select count from product where id = 37 for update;
只有拿到行锁的才能执行,其他的全部阻塞在数据库上。
随着线程不断增大,可能因为这一个行锁就把DB给打挂了,线程一个一个的执行。
效率不行。。。

2、乐观锁:了解下?

加一个version字段,版本号
锁的粒度更细,执行语句的一瞬间,比对一下原来的库里面,CAS原理,总有个先后吧…

问题:用version T0,T1,T2取抢,T0抢到了,T3 T4 T5 (T3抢到了,但是T1 T2 不乐意了)可能出现后到的先抢到秒杀商品(抢红包不能用,秒杀可用)
乐观锁也会影响性能,Innodb能执行事务,事务回滚时,redolog undolog binlog 都需要维护。

3、那咋玩?
防止超卖,根据Sql语句控制,就是类似于我在执行update操作的时候,这一行是一个事务(默认加了排他锁)。这一行不能被任何其他线程修改和读写在这里插入图片描述就是控制,别超过库存数了,悠着点来。再配合事务以及排他锁。

三、下单业务高并发优化思路

前提:10个人进来下单了,库存以及卖完了,其他请求进来已经无意义了
所以也给下单这块咱们来个二级缓存呗

一级缓存部分:

本地Cache中,首先走一下判断当前商品库存是否为0(标识无库存为true?),如果为true则不能下单了。那么下次再有请求直接打到本地JVM中,直接返回false,不用再走逻辑了,更快。

二级缓存部分
下单这个请求没必要全部打到DB上,可以把秒杀商品的库存先放在redis里,可以做预减。
redis的 Decr的操作。
如果库存<0则,再把库存加回去,再返回个false 为啥呢?(补偿机制),以防出现少卖。并且向本地cache中标记该商品无货了(标识无库存为true)

四、高并发场景下存在的问题(少卖)

1、Redis预剪了库存,继续执行下面的逻辑,突然出现异常了,也就是数据库中并没减,那我是不是应该把库存再加回去(通过catch执行),也就是说,redis中的库存信息会加1,同时本地Cache中((标识无库存为true)

2、但是本地的JVM也只能改本地的,不能改其他JVM的订单服务(解决思路:使用redis的发布订阅模式,创建一个channel,像里面发布消息,订单服务群各个服务去监听channel) 还有网络抖动等问题(某个服务没收到,因为channel无ACK机制)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值