商品订单库存一致性

首先先确认方案:

方案1 :下单后减库存,用户下单,然后库存加锁,判断库存是否充足,用户下单完成,减库存,最后释放库存锁。
方案2:支付才减库存,用户支付,然后库存加锁,判断库存是否充足,用户支付完成,减库存,最后释放库存锁。

两种方案的比较

方法1
(1)如果100人同时下单,只有一个人可以下单成功
(2)此时订单应该有一个过期状态,如果订单过期,库存加锁并回写库存后释放锁
方案2
(1)100人可以同时下单,但是100个人付款时,只有一个人可以付款成功
正常情况下,商品加入购物车的用户>>>下单的用户>=付款的用户。如果从库存加锁的角度来说,在下单的时候加锁,那么高并发下用户的体验可能变差,因为同时下单只有一个人可以下单成功,而且服务器性能可能会变差;下单的请求变多,那么请求加锁的次数也变多了,而支付的用户可能远小于下单的用户,请求加锁的次数理论上回少不少。

建议:

普通的电商项目我认为方案一就够了,因为下单的流程简单,而支付可能涉及到很多业务,如果支付里面锁库存,考虑的东西会有点多,
但是在高并发和秒杀的场景下,可能就要在支付的时候锁库存,从业务的角度来说,手快有,手慢无;从代码的角度来说,支付跟减少库存高度耦合,出现超卖,库存不一致的情况大大降低,如果下单锁库存,万一用户取消订单,那库存还要加回去,这种情况下高并发出现库存与实际消费不一致的可能性比较大。而且还有一个好处,秒杀场景在支付的时候锁可以保证所有的唱片都卖出去,而在下单的时候加锁,可能有的用户取消订单,到秒杀结束时候有产品没有卖出去,到秒杀结束时产品没有卖出。如果是老板肯定要全部卖出去。

实现方式以及优化

商品订单库存这个业务不仅仅只有用户下单,还要再管理后台提供上家修改库存的入口,那么这样就有两处需要用到库存,必须要考虑金证的问题

单体架构的实现

单体架构的实现是这个业务最简单的,也是性能最查的
在这里插入图片描述
单体架构中,不管是用户操作还是管理员后台操作库存都要放在里面,然后部署到机器上,吃屎库存锁是个全局锁,用户下单,管理员要修改库存都要从全局的咀村锁拿到锁,执行完业务代码再释放。
这种单体架构就会出现一个问题,耦合度太高,一旦管理后台修改库存占用库存锁,那么用户就不能下单购买商品了,如果是购物量不多的业务,单体架构是基本可以满足需求的。这种成本低,以维护,但是不能支撑高并发,
想大部分中小型公司,一天的订单我感觉也就1000以内,单体架构完全够用了,不需要改成下面,这种,增加幂等性。

优化方案

如果说业务增长块订单量增大,那么上面的单体架构就有局限性了。特别是现在互联网公司的架构大部分都是微服务分布式。
(1)首先,每次加锁后,都需要从数据库查库存,判断库存,然后下单也要操作数据库修改库存。数据库的操作需要时间成本,大流量如果一个用户下单时间太慢,其他用户都要等待她处理完,用户体验太差
(2) 其次现在架构大部分是分布式,用户下单减库存和管理后台修改库存一般是拆分程两个服务i-下单服务和库存服务

优化的第一步:

要解决下单因为操作数据库耗时过长的问题,我们可以把库存放到缓存中(一般是redis),然后对redis中的库存加redis锁,执行下单,对redis中的库存进行减库存。这么做的好处是提升了用户下单的速率,加大了并发量;其次用户下单跟管理后台的业务解耦了,为以后拆分服务做扩展。如下图:

在这里插入图片描述

### 抢购场景下的分布式事务数据一致性解决方案 在抢购场景中,由于高并发请求的存在,传统的单体事务机制难以满足需求。为了保证分布式环境中的数据一致性,可以采用以下几种常见方案: #### 1. 基于消息队列的最终一致性方案 此方法通过引入消息中间件(如Kafka、RabbitMQ),将订单创建和库存扣减的操作解耦[^1]。当用户下单成功后,系统会向消息队列发送一条消息通知库存服务减少对应商品的数量。如果库存扣减失败,则可以通过补偿机制重新尝试执行。 优点在于能够有效缓解流量高峰带来的压力;缺点则是存在短暂的时间窗口,在这段时间内可能会出现超卖现象。因此还需要配合其他手段比如乐观锁来进一步增强控制力。 ```java // Java伪代码示例:利用消息驱动实现订单库存分离处理 @Service public class OrderService { @Autowired private RabbitTemplate rabbitTemplate; public void createOrder(Order order){ // 创建订单逻辑... // 发送消息给库存服务 rabbitTemplate.convertAndSend("inventory.exchange", "key", new InventoryDeductionMessage(order)); } } ``` #### 2. TCC (Try-Confirm-Cancel) 模式 TCC是一种强一致性的两阶段提交协议变种形式,适用于对实时性要求较高的业务场景。其核心思想是在实际修改资源之前先预留资源(Try),之后再确认(Confirm)或者取消(Cancel)[^3]。例如,在抢购过程中,“Try”阶段锁定一定数量的商品供后续操作使用;一旦整个流程顺利完成则调用“Confirm”,反之则触发“Cancel”。 该方式虽然复杂度较高但能较好地应对各种异常情况,确保即使发生部分失败也能回滚到初始状态从而维持全局一致性。 #### 3. 分布式锁技术 为了避免因多线程或多实例同时访问同一份共享资源而导致的竞争条件问题,可借助Redis等内存数据库提供的分布式锁功能来进行同步管理。每当某个客户端获取到了特定商品对应的唯一标识作为钥匙打开这把虚拟之锁以后才能继续往下走完成购买动作直至释放为止期间不允许任何其他人进来干扰。 需要注意的是设置合理的过期时间防止死锁以及考虑到网络延迟等因素可能造成误判的情况采取重试策略加以弥补不足之处。 --- #### 小结 综上所述,针对抢购这种特殊环境下涉及到跨多个子系统的交互行为时,推荐优先考虑基于事件驱动的消息传递模型辅以必要的保护措施诸如版本号校验或是悲观/乐观加锁等方式共同作用达成目标效果最佳平衡点既兼顾效率又不失精确程度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值