扣减库存余额 vs 记录购买数量,你选择哪一个方案?

设计库存系统的时候,如何记录当前的库存余额,有两种实现方案,我们应该如何决策呢?

方案1:扣减库存余额

方案1:记录库存余额的方案是,每次购买时库存余额都减去购买数量。一旦库存余额小于等于 0,则无法再减少库存数量,商品则不可再售卖,直至库存得到补充。示例SQL如下

update inventory set cnt = cnt - #{buyCnt} WHERE productId = #{productId} AND cnt - #{buyCnt} >= 0


方案2 递增购买数量

方案2:记录售卖数量的方案是,每次购买时,已售卖数量 + 当前购买数量。加和以后,一旦已购买数量大于库存总数时,则库存不足,商品则不可再对外售卖,直至库存得到补充。

update inventory set cnt = cnt + #{buyCnt} WHERE productId = #{productId} AND cnt + #{buyCnt} <= totalCnt


比较两个方案的优劣

这两个方案都可以实现库存功能。但是在库存不足后,需要补充库存的场景,两个方案存在差异,存在优劣。

例如当前总库存为100,已售卖了51个,剩余库存为49个。按照方案1(库存余额)的要求,当库存从100增加到200时,除了库存总数需要增加,剩余库存数量也需要增加100个,变为149个。

然而,减少库存总数这一场景,方案1的实现方案更加复杂。当库存从100减少到50时,由于库存余额为49个,库存余额减掉50后,则为-1。因为库存余额为负数属于异常场景,所以需要将剩余库存设置为0。然而,这会引起数据的一致性问题。

因为库存余额不准确,所以 已售卖数量 = 库存总数 - 库存余额,这个等式也不再正确 ,如果商品需要展示 已售数量,使用这个公式就无法保证已售数量的准确性。

在方案1中,每次调整库存总数都需要调整库存余额,增加了操作复杂度。因为C端交易流程需要操作库存余额,B端调整库存总数也会涉及调整库存余额,BC端的库存操作需要互斥。此外 B端扣减库存余额也要考虑幂等,例如B端减少库存余额时,需要额外增加库存操作流水,否则SQL超时,再次重试就会多扣减库存余额。

此外B端减少库存余额时,如果希望针对 库存余额 为负数 的场景做特殊处理,就需要先使用用 select for update锁住库存记录,再尝试执行业务逻辑,设置合理的库存余额。否则因为C端不停地修改库存余额,余额一直在变化,B端无法准确的修改库存余额。

相比之下,方案2(记录售卖数量)则没有方案1的困境。增加或减少库存总数只需要调整相应的库存总数即可。甚至无需考虑幂等问题,因为多次更新库存总数也不会有问题。 当前售卖数量只有C端交易流程会修改,库存总数只有B端库存管理场景会修改。查询商品的已售卖数量只需要查库存的已售数量即可,而商品的库存余额可以通过库存总数减去已售数量得到。商品库存余额 = 库存总数 - 已售数量 ,BC端的操作不会影响这个等式的正确性。

综上所述,方案1使用库存余额更加复杂,并且没有明显的收益。而方案2记录售卖数量的方案更加简单,调整库存更加简洁优雅,而且不会出现数据一致性问题。通过记录售卖数量,很容易就可以知道当前商品的已售卖数量。

相关推荐
自由的疯3 小时前
Java Jenkins、Dockers和Kubernetes有什么区别
java·后端·架构
aiopencode3 小时前
tcpdump 抓包内容分析实战,快速定位到结论的工程化套路(含真机抓包)
后端
用户673398017513 小时前
Docker部署单机版NacosV3.0版本并使用Nginx代理
后端
京东零售技术3 小时前
浅析cef在win和mac上的适配
后端
Java水解3 小时前
MySQL 中 ROW_NUMBER() 函数详解
后端·mysql
美团技术团队3 小时前
从0到1建设美团数据库容量评估系统
后端
云闲不收4 小时前
golang的一些技巧
开发语言·后端·golang
星星电灯猴4 小时前
iOS 开发环境搭建全攻略,系统配置、开发工具与跨平台使用开心上架的上架实战指南
后端
Flobby5294 小时前
「JMM+Java锁+AQS」 知识图谱
java·后端
焰火19994 小时前
[Java]Redisson的分布式锁及看门狗机制
java·后端