高并发下超卖问题的解决方案

什么是超卖

现象举例:比如某商品库存为1,用户一和用户二同时购买。用户一提交订单库存修改为0,用户二在不知道的情况下再次提交订单,库存被再次修改为-1.这就是超卖现象。

原理:是因为数据库底层的读写操作是可以同时进行的,虽然写操作默认是带有隐式锁(即对同一数据部门同时进行写炒作)但是读炒作默认是不带锁的,所有当用户一减去库存时,用户二依然可以读取到库存为1的情况,这就出现的超卖的情况。

超卖的解决方案

前端解决方案

1,缓存静态数据
2,搭建负载均衡集群,目前采用较多的为nginx
3,进行ip限制,限制同一个ip单位时间内发起的请求数量
4,考虑使用系统降级
同过以上方式降低并发量

后端解决方案

1,增加数据库判断
并发情况下,判断库存和修改库存是存在线程安全问题的,说以在进行最终修改库存时,需要增加一个判断机制,判断当前库存是否小于0,

begin()
update orders set count=count-1 where cound>0 and sku_id = '123'
commit()

这是利用了update的行级锁,说以可以保证线程安全,避免库存出现负数的情况。同时应为加了锁,你会发现100个线程访问,最终只有获取锁的对象执行成功,其他都会失败,影响性能。

2,前置数据到redis
2.1系统启动后,初始化sku信息到redis数据库,记录其可用量和锁定量
2.2使用乐观锁,采用redis的watch机制。逻辑为:
1.定义门票号变量,设置初始值为0。watchkey
2.watch该变量,watch(watchkey);
3.使用redis事务加减库存。首先获取可用量和抢购量比较,如果curcount>buycount,那么正常执行减库存和加锁定量操作:
multi;
redis incr watchkey;
redis decrby curcount buycount;
redis incrby lockcount buycount;
exec;
由于上述操作都在事务内进行,一旦watchkey被其他的事务修改过,那么exec将返回nil,如此就放弃本次请求。一般都是在循环中重复尝试直到成功或没有可用量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值