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

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

update number set x=x-1 where (x -1 ) >= 0;
为什么这条语句会出现超卖
16437 次点击
所在节点    Java
84 条回复
cqu1980
2018-11-21 09:19:13 +08:00
这个只是保证减库存后,库存数不会变成负数,和超卖是两个概念....
CSDreamer
2018-11-21 09:20:26 +08:00
秒杀请求走队列,消费者去消费,就不出现这种情况,不能完全基于 mysql 做秒杀
juneszh
2018-11-21 09:20:37 +08:00
难道楼主没有用 ROW_COUNT()来获取 UPDATE 语句的执行结果,而是直接用 EXEC()的返回值?
cqu1980
2018-11-21 09:23:13 +08:00
估计没做 43 楼的操作~~~~~~
awanabe
2018-11-21 09:23:52 +08:00
事务搞到串行当然可以避免的 那双十一的订单可能要几年才能处理完吧?
springGun
2018-11-21 09:27:35 +08:00
为什么不是 where x>0
ikaros
2018-11-21 09:34:51 +08:00
放在内存里用互斥锁操作,或者先锁表
kismetX
2018-11-21 09:38:46 +08:00
如果是 innodb,并且加了事务的话,是不会出现负数的情况的,每行数据是都有一个事务版本号的,修改前 innodb 引擎是会检查事务版本号再更改的,这个就是解决前面部分说幻读的机制,而且这也是行级锁,讲道理,如果判断了返回的影响行数,不仅不会成为负数,也不会比库存多订单
tabris17
2018-11-21 09:42:32 +08:00
我猜 lz 用的 MyISAM 引擎,大家散了吧
shenhhd
2018-11-21 09:46:59 +08:00
坐等大神终结此问题~~~~
cyhulk
2018-11-21 09:51:43 +08:00
@tabris17 不是,这只是我无意间看网上的文章看到的,不信你百度,秒杀超卖,很多都这样写,所以我就很奇怪,1000 个并发去操作也没有问题,所以就问问了,还有大家纠结的锁,其实即使是 RC 隔离级别下,也会有 X 锁,也不会出现问题,这个我一会验证下。
amon
2018-11-21 10:00:47 +08:00
如果是 InnoDB,加了合适的事务的话,不会有问题吧。
另外秒杀这种还是走队列。
linxy
2018-11-21 10:02:28 +08:00
按 LZ 的说法,搜了一下来源,原来是别人博客里的。。。。。
cyhulk
2018-11-21 10:02:50 +08:00
@amon 我知道这个,这个只是网上的文章,我也只是质疑别人的结论。
cyssxt
2018-11-21 10:05:28 +08:00
通过数据库锁并不是好的办法 需要在最上层杜绝 比如 200 的的秒杀量 10000 的访问量 后面的人 99800 的请求应该直接返回失败 个人觉得最好的办法是用队列去处理 前端轮回处理秒杀结果
cyssxt
2018-11-21 10:06:33 +08:00
@cyssxt 错了 是 9800 数学老师要活过来
tingfang
2018-11-21 10:23:43 +08:00
不可能超卖的吧?
karllynn
2018-11-21 10:25:10 +08:00
这个不会超卖啊,这跟事务也没啥关系,这是数据库的基本保证吧

另外为啥不直接写`where x > 0`…
grandpa
2018-11-21 10:30:13 +08:00
有检查 affected rows 吗
cyhulk
2018-11-21 10:39:36 +08:00
@linxy 我就是看别人的博客出现的疑虑

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

https://www.v2ex.com/t/509707

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

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

© 2021 V2EX