高并发场景下解决秒杀超卖问题的绝招

原创 爱他就关注他---> Java分享客栈 2023-10-23 12:25 发表于湖北

收录于合集

#java95个

#秒杀2个

#乐观锁1个

点击关注公众号,Java干货及时送达👇

Java分享客栈

分享IT互联网主流技术,包括Java、SpringBoot、SpringCloud-alibaba、Redis缓存、MQ队列、网络编程、websocket通信、netty、docker、k8s等技术及多年工作经验分享和感悟。

96篇原创内容

公众号

最近脖子后颈里面长了东西,正在医院检查,想必是熬夜太多导致的,具体情况还不清楚。

再次呼吁大家,保护好自己的身体,程序员的累不是传统意义上的累,有时候随着年纪增长会体现在心理上。

希望大家都顺顺利利,健健康康的。

更新可能会没那么准时了,希望大家谅解并继续支持哈。

前言

首先要明确一点,那就是解决超卖问题最直接且最稳妥的方式就是数据库,而非代码控制,代码中的逻辑很难去控制这种场景。

只有利用数据库的锁机制和唯一索引才能彻底保证不出现超卖。

场景解释

举两个例子解释下高并发场景:

1)、秒杀过程中,库存有10个商品,当还剩下1个的时候,同时有2个请求访问者1个商品,结果导致数据库中的库存变成-1;

2)、秒杀过程中,1个用户同时发出2个请求,结果导致秒杀订单生成2个,等于说1个用户秒杀到了2个商品。

方案提供

两种方式:

1、使用数据库自带行锁机制;

2、使用version版本号实现乐观锁。

第1种方式属于悲观锁,其实完全可以解决,性能也不是无法接受,但从技术的角度上而言,还是推荐第2种方式,一来性能更高,二来不会被击穿库存。

比如:200个请求访问100个库存,大概会秒杀成功60多个或70多个,还剩余一小部分库存可供用户重试,容错率更高。

方案说明

1、行锁方式

这种方式就很简单了,只要在mapper中的语句加上 库存 > 0 的条件判断即可,这样就能触发数据库行锁机制。

示例:

update meite_seckill set inventory=inventory - 1 where seckill_id = #{seckillId} and inventory > 0;

使用数据库自带的行锁机制,假如有200个请求访问100个库存,那么会有100个秒杀成功。

2、version方式

这种方式的原理就是在数据库中,针对秒杀库存业务关联的表中新增一个version字段。

乐观锁通常有以下几个步骤:

1) 在数据库表中添加一个用于记录版本号或时间戳的字段;

2) 当事务要读取数据时,会获取数据的版本号或时间戳并保存下来;

3) 当事务要更新数据时,会检查该数据的版本号或时间戳是否与之前保存的一致。

如果一致,则表示没有其他事务对该数据进行过修改,可以继续执行更新操作,并将版本号或时间戳加一。

如果不一致,则表示有其他事务对该数据进行了修改,当前事务需要根据业务逻辑进行相应的处理,如放弃操作或重新尝试。

示例:

update meite_seckill set inventory = inventory - 1, version = version + 1 where seckill_id = #{seckillId} and inventory > 0 and version = #{version};

使用数据库自带的行锁机制,假如有200个请求访问100个库存,那么可能会有60-70个秒杀成功,这就极大的增加了容错率。

总结

行锁机制和乐观锁机制各有优劣,适用于不同的场景和需求:

  • 行锁机制适合对并发控制要求严格的场景,可以避免并发修改数据造成的问题,但可能导致性能下降。

  • 版本号的乐观锁机制适用于并发量较高、冲突概率较小的场景,可以在保证一致性的同时提高系统的并发性能。

如何使用还是要根据具体业务场景来决定,但还是以前提过的那句话,类似问题的处理方式学习大厂的经验即可,那就是结合使用。

好了,今天的小知识,你学会了吗?

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值