mysql怎么做库存管理_电商中的库存管理实现-mysql与redis

电商库存管理是核心业务,本文探讨了MySQL和Redis在处理并发扣减库存时的优缺点。MySQL在并发场景下可能出现超卖,通过特定更新策略能缓解但影响性能。Redis提供原子性操作,解决性能问题但牺牲了一致性。解决方案可能涉及异步队列和定时扣减库存。
摘要由CSDN通过智能技术生成

库存是电商系统的核心环节,如何做到不少卖,不超卖是库存关心的核心业务问题。业务量大时带来的问题是如何更快速的处理库存计算。

此处以最简模式来讨论库存设计。

以下内容只做分析,不能直接套用,欢迎各位同道前来交流指正

库存模型:sku,num。

sku是标示商品的唯一编号,num是商品的数量。

订单处理时需扣减商品库存。

mysql实现

库存初始数据:

20f0412f3e3d863da23526bbb0b29a57.png 

mysql隔离级别READ-COMMITTED

扣减1001库存7:

10-7=3;

3>0;

开始扣减库存

UPDATE stock SET num=3 WHERE sku=1001;

在串行执行情况下以上逻辑是正确的处理方式。

如果是并发执行,可能会出现这种情况:

10-7=3;

库存在另外一个线程中被修改为5

UPDATE stock SET num=3 WHERE sku=1001;

库存最终被修改为3

一共卖出5+7=12个商品,实际总商品数是10,超卖发生。

为解决超卖引入如下方案:

10-7=3;

3>0;

开始扣减库存

库存在另外一个线程中被修改为5

UPDATE stock SET num=num-7 WHERE num>=7 AND sku=1001;

update失败,超卖解决。

考虑到订单的商品有多个,那在并发执行的情况下是否还是正常呢?

现有订单1,订单2同时处理,都是1001扣减库存5,1002扣减库存10

订单1:

UPDATE stock SET num=num-5 WHERE num>=5 AND sku=1001;

UPDATE stock SET num=num-10 WHERE num>=10 AND sku=1002;

订单2:

UPDATE stock SET num=num-10 WHERE num>=10 AND sku=1002;

UPDATE stock SET num=num-5 WHERE num>=5 AND sku=1001;

若sql执行情况是订单1先修改1001,订单2修改1002,这个时候产生死锁,有一个订单必然会失败。

少卖发生。

如果是订单2中第二个商品是1003会怎么样呢?

两个订单的库存修改会变成串行执行。

这种情况下会带来性能下降的问题,事务超时的时候会发生多个订单失败的情况。

多个订单失败后如果订单依然要处理,此时库存没有扣减,又会发生超卖。

结论:mysql可以保证数据一致性和持久性,但是性能不高,在量级较高的情况下库存并没有控制好少卖超卖的情况。

redis实现

mysql的缺点是如此显而易见,为了解决这个问题,现在引入redis。

redis的读写速度快,数据操作都在内存中运行,性能必然比mysql高。

string类型提供了decrby方法,可以以原子方式对string做减法。

对1001库存减5:

decrby 1001 5

获得返回值,如果小于0则执行

incrby 1001 5

并且所有相关数据回滚

在多线程环境中会有多个订单同时回滚,库存充足的情况。产生这种现象后,失败的订单可以留待下次再行处理。

但是库存的值并不能用来做实时计算,因为失败订单的库存没有进行计算。

redis没有事务,无法保证数据一致性。

结论:redis解决了性能问题,但是数据一致性无法保证。

其它

为解决mysql问题,可以结合异步定时扣减库存,队列做。

最后,不管用mysql还是redis 都各有优缺点.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值