当前位置:网站首页>【Redis实现秒杀业务②】超卖问题的解决方案
【Redis实现秒杀业务②】超卖问题的解决方案
2022-06-24 20:01:00 【步尔斯特】
我们在上一篇的文章中,实现了秒杀的基本业务,但是在并发的场景下,我们会发现代码存在诸多问题,超卖就是经典的问题之一。让我们来一起研究一下这玩意。
什么是超卖
超卖现象是秒杀业务中常见的现象,意指用户在购买指定商品的过程中,售卖的商品超过了商户的预期。
超卖是怎么产生的
如果只剩最后一件商品的时候,恰好这时有两个线程同时进入这个红色框框,就会一起进入更新的代码,于是就会产生超卖现象了。

图解超卖
正常情况

超卖情况
解决方案
超卖问题是典型的多线程安全问题,针对这一问题的常见解决方案就是加锁:
- 悲观锁
- 乐观锁
悲观锁
认为线程安全问题一定会发生,因此在操作数据之前先获取锁,确保线程串行执行。
例如Synchronized、Lock都属于悲观锁。
悲观并发控制实际上是“先取锁再访问”的保守策略,为数据处理的安全提供了保证。
但是在效率方面,处理加锁的机制会让数据库产生额外的开销,还有增加产生死锁的机会,同时也会降低并发性能。
悲观锁的实现----MySQL版
要使用悲观锁,我们必须关闭mysql数据库的自动提交属性。MySQL默认使用autocommit模式,也就是说,当你执行一个更新操作后,MySQL会立刻将结果进行提交。我们可以使用命令设置MySQL为非autocommit模式:set autocommit=0;
//开始事务
begin;
//查询出商品库存信息,使用 for update 加上排它锁
select quantity from items where id=1 for update;
//修改商品库存
update items set quantity=100 where id = 1;
//提交事务
commit;
乐观锁
认为线程安全问题不一定会发生,因此不加锁,只是在更新数据时去判断有没有其它线程对数据做了修改。
如果没有修改则认为是安全的,自己才更新数据。
如果已经被其它线程修改说明发生了安全问题,此时可以重试或异常。
相对于悲观锁,在对数据库进行处理的时候,乐观锁并不会使用数据库提供的锁机制。一般的实现乐观锁的方式就是记录数据版本。
乐观锁不会产生任何锁和死锁,拥有更好的性能。
乐观锁的实现
通过一个单独的可以顺序递增的version字段,可以避免ABA问题:
//查询出商品信息,version = 1
select version from items where id=1
//修改商品库存为2
update items set quantity=2,version = 3 where id=1 and version = 2;
除了version以外,还可以使用时间戳,因为时间戳天然具有顺序递增性。
减小乐观锁力度,可以最大程度的提升吞吐率,提高并发能力:
//修改商品库存
update item
set quantity=quantity - 1
where id = 1 and quantity - 1 > 0
选择悲观锁还是乐观锁
- 乐观锁并未真正加锁,效率高。然而,如果锁的粒度掌握不好,更新失败的概率就会比较高,容易发生业务失败。
- 悲观锁依赖数据库锁,效率低。更新失败的概率比较低。
- 在高并发的业务场景下,悲观锁越来越少被使用了。
我们下一章就来具体实现一下乐观锁的方案。
边栏推荐
- Paper review: U2 net, u-net composed of u-net
- Use of navigation and navigationui
- D does not require opapply() as a domain
- 不重要的token可以提前停止计算!英伟达提出自适应token的高效视觉Transformer网络A-ViT,提高模型的吞吐量!...
- 5-minute NLP: summary of 3 pre training libraries for rapid realization of NER
- Simple collation of Web cache
- Qiniu cloud uploads video to get the first frame of video
- [leaderboard] Carla leaderboard leaderboard leaderboard operation and participation in hands-on teaching
- Uniapp encapsulated incentive advertisement, screen insert advertisement and banner advertisement
- Usage of ViewModel and livedata in jetpack
猜你喜欢

Apk slimming compression experience

JDBC —— 数据库连接

Im instant messaging development application keeping alive process anti kill

Why are life science enterprises on the cloud in succession?

Power application of 5g DTU wireless communication module

Registration method of native method in JNI

无需显示屏的VNC Viewer远程连接树莓派
Modstart: embrace new technologies and take the lead in supporting laravel 9.0

Use and click of multitypeadapter in recycleview

Wallpaper applet wechat applet
随机推荐
In the process of enterprise development, I found that a colleague used the select * from where condition for update
More pictures | explain the Nacos parameters in detail!
How to quickly open traffic master for wechat applet
【排行榜】Carla leaderboard 排行榜 运行与参与手把手教学
Human body transformation vs digital Avatar
Ott marketing is booming. How should businesses invest?
2021-11-07
Jar package merging using Apache ant
Why are life science enterprises on the cloud in succession?
Related operations of ansible and Playbook
Basic summary of MySQL database knowledge
Go crawler framework -colly actual combat (II) -- Douban top250 crawling
Report on operation pattern and future prospect of global and Chinese propyl isovalerate industry from 2022 to 2028
Common redis commands in Linux system
无需显示屏的VNC Viewer远程连接树莓派
A small program written this week
Unimportant tokens can be stopped in advance! NVIDIA proposes an efficient visual transformer network a-vit with adaptive token to improve the throughput of the model
Technology sharing | wvp+zlmediakit realizes streaming playback of camera gb28181
The third generation of power electronics semiconductors: SiC MOSFET learning notes (V) research on driving power supply
Is it so difficult to calculate the REM size of the web page according to the design draft?