高并发下防止库存超卖——方案1关系数据库锁

所谓库存超卖是指在并发量大的情况下,卖出去的商品数量比实际库存多,如秒杀系统

1、超卖举例:
总库存:4个商品 ; 请求人:a、1个商品 b、2个商品 c、3个商品
伪代码:
select 库存数量 from 库存表  where 商品id=XXX;
if  库存数量-扣减库存数量 

update 库存表 set 库存数量=库存数量-扣减商品数量 where  商品id=XXX;

这种方法先查看库存,然后判断有库存就下单操作,看似没有,仔细分析下
1. 两个事务同时读取同一个商品,inndb对select语句不会加锁,就算加共享锁,其他事务也可以读。所以3个事务得到的库存都是4
2. 两个事务同时修改操作,mysql会将并发update语句串行化处理,一个一个执行。这样当第一个update操作的时候会生成排他锁,其他事务等待,当第一个事务提交后,第二个事务得到锁继续update操作。那这样的话库存就为-1了。
3. 结论:高并发情况下会出现用户a、b、c同时读到库存为4,然后串行成功执行了扣减库存操作,这样执行完后,库存肯定为负数了。

2、数据库行级锁
优点:mysql的indb引擎的for update语句是行级数据锁,定能防止并发。
缺点:数据库并发性能本来一般就是系统的瓶颈,行级锁会进一步降低数据库并发性能,但是金融方面一般用这种行级锁方案比较多,通过垂直和水平分库来提升数据库的并发性能。
select 库存数量 from 库存表 where 商品id=XXX for update;
update 库存表 set 库存数量=库存数量-XXX  where 商品id=XXX;

3、数据库乐观锁
优点:相比数据库行级锁性能更高
缺点:在关系数据库中此种场景还是比较合适的,暂未发现缺点
伪代码:
更新数量 = upddate 库存表 set  库存数量=库存数量

4、代码demon实现
地址:springBoot+mybatis版【待抽空实现demon】
说明:demon有1、多线程并发下出现超卖 2、数据库行级锁避免超卖 3、数据库乐观锁避免超卖

5、参考文章 
https://blog.csdn.net/caomiao2006/article/details/38568825
https://blog.csdn.net/zhoudaxia/article/details/38067003


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值