购物车结算问题

2021-01-07 14:22:58 +08:00
 jtping

购物车结算生成订单时,需要对购物车中每件商品进行库存校验,和库存预扣除

我现在想到了两种方案

第一种:

是每次只获取一个商品的锁,然后查询判断库存,预扣除,然后释放锁,之后的商品都走一遍这个流程

第二种:

是一次性获取到所有需要结算的商品的锁,然后一次性查询出所有商品库存,进行库存判断,预扣除,然后释放所有的锁

两种方法目前我能想到的利弊:

第一种如果商品多了,访问数据库就会比较频繁,但是锁单件商品的时间短了

第二种如果商品多了,访问数据库虽然不会很频繁,但锁持有的时间肯定比第一种方法要长(而且是所有需要结算商品的锁)

哪种方法比较合适,或者有什么更好的方法

希望各位大神指导指导

2108 次点击
所在节点    程序员
12 条回复
kop1989
2021-01-07 14:29:54 +08:00
从我的经验上,我推荐用第二种。
因为真正的业务场景比你设想的要复杂。
1 、有商品组合(套装)的可能。
2 、有消费者凑单的可能。
3 、有二级库的可能。
jtping
2021-01-07 14:37:41 +08:00
@kop1989 多谢指导 目前我也比较倾向第二种 但一次性持的锁过多会不会对后面等待的用户不太友好
Mitt
2021-01-07 14:42:05 +08:00
@jtping #2 我没做过这类的,不过我觉得可以考虑把库存缓存到 redis 了,等真正订单处理完成后再同步到数据库里,这样你的锁代价就很低了
kop1989
2021-01-07 14:46:31 +08:00
@jtping #2 这就要看你真正的业务需求(也就是预计的网站流量、商品规模而定)
比如像京东这种庞然巨物,就需要同时支持消费者“如果 A 没了,那我就不要 B,但保留 C”,“如果 A 没货,我就不买了”,“A 没了,我依然要买其他”,“ABC 是个套装,我用了个套装优惠券”等需求。

这时候如果你选择第一种,在数据链路层来卡死只锁单件商品,就会面临频繁的锁》扣库》释放》异常》锁》退库》释放。
这时候造成的系统性能浪费未见得更低,以及会带来业务展现上的不稳定(消费者会面临这款产品的库存数量“频繁抖动”)。也增加了上层的业务实现复杂度。
jtping
2021-01-07 14:53:17 +08:00
@Mitt 多谢指导 我之前一直在考虑两种方法的利弊 没往这方面想
jtping
2021-01-07 14:56:47 +08:00
@kop1989 豁然开朗! 是我之前没考虑周全
YouLMAO
2021-01-07 19:10:50 +08:00
jd, ali 都是 TCC 分布式事务, 不是数据库加锁的
YouLMAO
2021-01-08 00:40:35 +08:00
如果 A 没了,那我就不要 B,但保留 C”,“如果 A 没货,我就不买了”,“A 没了,我依然要买其他 @kop1989 京东阿里哪个页面是这个逻辑?不符合中国人原理
pinews
2021-01-08 10:22:50 +08:00
小白来交流下,减库存这个操作,本身不就自带锁吗,第一种和第二种有什么区别?第二种怎么减少数据库访问了?不同的商品可以一块减?
就算有区别,锁的总耗时没较少,也说不上增加吧,问题应该是解决总耗时吧。

要解决总耗时只能用缓存数据库了啊,redis memcached mysql 的 memory 表都可以吧,

另外如果处理订单除了减库存,还要减红包,发短信,发邮件,赠送积分,红包等等,那可以考虑协程异步处理(消息队列)了啊

不知道说的对不对。
jtping
2021-01-08 15:40:40 +08:00
@pinews 假设购物车一次性结算 100 件商品

第一种方法就要执行 100 遍 update 语句来更新每件商品的库存 每件商品执行一次 但每次只需要拿一件商品的锁

第二种方法将 100 件商品库存用一个 update 语句更新 因为需要一起更新 所以就需要同时持有 100 件商品的锁

大概是这么个意思
pinews
2021-01-08 16:16:51 +08:00
@jtping 如果所有商品减库存都是相同的,比如-1,的确可以一起 update,明白了

那就考虑缓存数据库呗,期待你的结果。
jtping
2021-01-08 16:23:51 +08:00
@pinews
哈哈其实不必都相同 批量 update 网上一找一大堆

我目前用的是第二种方案 利弊上面也有大神说了

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

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

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

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

© 2021 V2EX