有懂秒杀的兄弟吗?为什么 mysql 这样会出现超卖的问题

2018 年 11 月 20 日
 cyhulk
首先设定一个前提,为了防止超卖现象,所有减库存操作都需要进行一次减后检查,保证减完不能等于负数。(由于 MySQL 事务的特性,这种方法只能降低超卖的数量,但是不可能完全避免超卖)

update number set x=x-1 where (x -1 ) >= 0;
为什么这条语句会出现超卖
17186 次点击
所在节点    Java
84 条回复
lihongjie0209
2018 年 11 月 20 日
你的事务级别是什么?
iloveyou
2018 年 11 月 20 日
悲观锁乐观锁
WeaponXu
2018 年 11 月 20 日
取数据的时候要锁一下
mmdsun
2018 年 11 月 20 日
update number set x=x-1 where x >0 这样写肯定不会超卖的。RR 隔离级别
opengps
2018 年 11 月 20 日
秒杀是个高并发的东西,不适合用数据库控制
gejun123456
2018 年 11 月 20 日
你这样写肯定不会的
blue0125
2018 年 11 月 20 日
据说用 Redis 可以
xavier007
2018 年 11 月 20 日
队列!比如小米原来的秒杀,就是有个中间页,然后通过队列限制进入实际购买页。另外数据库更新也可以利用队列。这样限制了更新数据库的并发量
zjsxwc
2018 年 11 月 20 日
这种 sql 明显会超卖的啊, mysql 默认的事务级别是允许幻读的, 使用队列处理秒杀是最佳实践.
ilyh
2018 年 11 月 20 日
你这样写是不会的, mysql 默认的隔离级别是可重复读, update set 操作是当前读, 会加锁的. 和幻读没有关系
luozic
2018 年 11 月 20 日
事务,你这只是 update,
heww
2018 年 11 月 20 日
用 select for update 来做
o00o
2018 年 11 月 20 日
艺高人胆大,我这都是在 Java 端用线程锁判断
limuyan44
2018 年 11 月 20 日
mysql 默认的 rr 级别不会的,另,这个和上面说的幻读有毛关系。。
Raymon111111
2018 年 11 月 20 日
这样写应该不会超卖啊
mayday526
2018 年 11 月 20 日
默认级别 RR,理论上不会,那么问题来了,为什么这样还是会超卖呢
leriou
2018 年 11 月 20 日
秒杀用 redis 分布式锁服务
insert000
2018 年 11 月 20 日
当并发进来的时候 x-1 可能是同时的,并且 x 设置成非负
Va1n3R
2018 年 11 月 20 日
了解一下安全界的条件竞争漏洞~
cheeseyu1994
2018 年 11 月 20 日
这样会超卖吗?等答案|ω・)
是不是没有对 mysql 操作结果进行判断就直接写入订单了?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://v2ex.xtra.eu.org/t/509707

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX