关于秒杀一般是如何保证库存操作的原子性的

2019-11-27 22:45:42 +08:00
 yejianmail
需要 java 做一个用户不太多的秒杀,springboot 加 mariadb,涉及库存操作的地方已加锁同步,事务隔离级别为 read-commit,偶尔出现剩余库存为-1,初步认为是数据库出现了幻读,这样的抢单一般是用什么技术实现的,如果并发不高,是不是也必须上 redis,有大佬指导下么?
4933 次点击
所在节点    程序员
37 条回复
renmu
2019-11-27 22:50:50 +08:00
一律返回失败,几秒后返回假数据到前端(狗头保命)
lhx2008
2019-11-27 22:53:24 +08:00
读已提交肯定出问题啊,因为他其实是基于 MVCC 的,比如说现在两个事务都看到只有一个库存,他就直接都做减库存操作了。不过你说了加锁,可能加的位置不对吧。
MeteorCat
2019-11-27 22:53:44 +08:00
不要假设并发不高,我今年也是假设并发不高,哪知道不知道哪里天杀直接爆破公司项目接口
lhx2008
2019-11-27 22:55:31 +08:00
最简单的方法肯定是 redis 做一个 lua 递减,或者一个分布式锁,程序内的锁,多副本运行就死了
lhx2008
2019-11-27 22:56:46 +08:00
如果是纯 mysql 的话,也可以用版本乐观锁的,但是读已提交还是不一定能生效。
shoaly
2019-11-27 22:58:48 +08:00
跟客户关系好的话...让她多准备几份商品.
yejianmail
2019-11-27 23:07:47 +08:00
@lhx2008 涉及两个方法一个是加减,一个是查看剩余库存,锁是同一个对象,事务应该是默认的 require
yejianmail
2019-11-27 23:08:30 +08:00
@renmu 最后一结算交易额为 0
yejianmail
2019-11-27 23:11:54 +08:00
@lhx2008 我看到网上的一些实现就是用的一个 guava 的工具类来限流,然后用 redis 的递增或者递减来保证库存操作原子性,没看明白退还库存为什么一定要用 lua 脚本
des
2019-11-27 23:29:22 +08:00
这种不是有很多讨论的么?
提前把数据在库里生成好也行,每一个商品算一条记录,删除成功进行后续操作
用 redis 也行,不过还是建议用 redis

这种东西不适合直接上锁
jeffh
2019-11-27 23:30:40 +08:00
mariadb 默认不是不重复读级别吗?更新库存的时候可以 update tab set value=value-1 where id=? and value>0;这相当于变相的乐观锁了吧。根据 sql 返回值可以知道是否 sql 执行成功
hhx
2019-11-27 23:36:15 +08:00
秒杀系统设计应该涵盖两个要点,即限流和同步。限流可以采用 controller 层 CAS 结合分布式锁例如 Redis 或 Zookeeper。同步可以采用 service 层锁或 MySQL 乐观锁。你提到了数据库的事务,你确定只将逻辑写入事务就能保证系统的正确性吗?
yejianmail
2019-11-27 23:38:16 +08:00
@jeffh 默认是可重复读级别,但是要开 binlog 才支持
mrdemonson
2019-11-27 23:38:26 +08:00
一直觉得奇怪,秒杀应该是锁内存数据吧,直接操作内存好了,为啥都要去搞数据库,和锁数据库
yejianmail
2019-11-27 23:39:31 +08:00
@jeffh 根据 sql 返回值这是个好办法,类似于 ignore into 看插入成功没
yejianmail
2019-11-27 23:40:56 +08:00
@mrdemonson 最终数据库需要和内存同步吧,这样才有办法结算
mxT52CRuqR6o5
2019-11-27 23:44:23 +08:00
据说淘宝的双十一秒杀是会超售的,不知道是真是假
yejianmail
2019-11-27 23:46:10 +08:00
@hhx 如果读取的数据没有脏读和幻读,可以保证业务的正确性
yejianmail
2019-11-27 23:47:10 +08:00
@mxT52CRuqR6o5 真的么,那我这就不算 bug 了呀,手动滑稽.jpg
petelin
2019-11-27 23:50:41 +08:00
为啥楼上的都不考虑可靠性和稳定性 内存数据库万一挂了呢?实时同步不就退化成...了吗

我觉得限流加锁完全没问题

比如你用 select for
update

一个人一个人的弄 怎么会有问题

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

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

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

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

© 2021 V2EX