订单减库存设计

一、扣减库存的三种方案

(1)下单减库存
  用户下单时减库存

  优点:实时减库存,避免付款时因库存不足减库存的问题

  缺点:恶意买家大量下单,将库存用完,但是不付款,真正想买的人买不到

(2)付款减库存
  下单页面显示最新的库存,下单时不会立即减库存,而是等到支付时才会减库存。

  优点:防止恶意买家大量下单用光库存,避免下单减库存的缺点

  缺点:下单页面显示的库存数可能不是最新的库存数,而库存数用完后,下单页面的库存数没有刷新,出现下单数超过库存数,若支付的订单数超过库存数,则会出现支付失败。

(3)预扣库存
  下单页面显示最新的库存,下单后保留这个库存一段时间(比如10分钟),超过保留时间后,库存释放。若保留时间过后再支付,如果没有库存,则支付失败。例如:要求30分钟内支付订单。

  优点:结合下单减库存的优点,实时减库存,且缓解恶意买家大量下单的问题,保留时间内未支付,则释放库存。

  缺点:保留时间内,恶意买家大量下单将库存用完。并发量很高的时候,依然会出现下单数超过库存数。

二、如何解决恶意买家下单的问题

这里的恶意买家指短时间内大量下单,将库存用完的买家。

(1)限制用户下单数量
  优点:限制恶意买家下单

  缺点:用户想要多买几件,被限制了,会降低销售量

(2)标识恶意买家
  优点:卖家设定一个备用库存,当支付时,库存已用完,扣减备用库存数,这就是常见的补货场景

  缺点:因高并发场景下,数据可能存在不一致性的问题

三、如何解决下单成功而支付失败(库存不足)的问题

(1)备用库存
  商品库存用完后,如果还有用户支付,直接扣减备用库存。

  优点:缓解部分用户支付失败的问题

  缺点:备用库存只能缓解问题,不能从根本上解决问题。另外备用库存针对普通商品可以,针对特殊商品这种库存少的,备用库存量也不会很大,还是会出现大量用户下单成功却因库存不足而支付失败的问题。

四、如何解决高并发下库存超卖的场景

库存超卖最简单的解释就是多成交了订单而发不了货。

场景:

用户A和B成功下单,在支付时扣减库存,当前库存数为10。因A和B查询库存时,都还有库存数,所以A和B都可以付款。

A和B同时支付,A和B支付完成后,可以看做两个请求回调后台系统扣减库存,有两个线程处理请求,两个线程查询出来的库存数 inventory=10,

然后A线程更新最终库存数 lastInventory=inventory - 1 = 9,

B线程更新库存数 lastInventory=inventory - 1 = 9。

而实际最终的库存应是8才对,这样就出现库存超卖的情况,而发不出货。

那如何解决库存超卖的情况呢?

1.SQL语句更新库存时,如果扣减库存后,库存数为负数,直接抛异常,利用事务的原子性进行自动回滚。

2.利用SQL语句更新库存,防止库存为负数

  1. UPDATE [库存表] SET 库存数 - 1 WHERE 库存数 - 1 > 0

  2.  

  3.  

    如果影响条数大于1,则表示扣减库存成功,否则订单失败,并退款。

五、秒杀场景下如何扣减库存

(1)下单减库存
因秒杀场景下,大部分用户都是想直接购买商品的,可以直接用下单减库存。

大量用户和恶意用户都是同时进行的,区别是正常用户会直接购买商品,恶意用户虽然在竞争抢购的名额,但是获取到的资格和普通用户一样,所以下单减库存在秒杀场景下,恶意用户下单并不能造成之前说的缺点。

而且下单直接扣减库存,这个方案更简单,在第一步就扣减库存了。

(2)将库存放到redis缓存中
  查询缓存要比查询数据库快,所以将库存数放在缓存中,直接在缓存中扣减库存。然后在通过MQ异步完成数据库处理。

(3)使用量自增方式
可以先增加已使用量,然后与设定的库存进行比较,如果超出,则将使用量减回去。

项目中用到了很多机制,但是没有总结出来,学习架构需要不断地总结。

六 第三方支付

1 支付成功多次回调:把减库存放在微信支付的成功回调URL的方法里面。但是微信支付成功之后微信支付平台会发送8次请求到回调地址。这样的做法就会导致库存减少,一定要验证返回的编号是否已经完成扣减。

原文地址:https://www.cnblogs.com/lichihua/p/10803305.html

时间: 2024-10-11 16:56:58

订单减库存设计的相关文章

EF+MySQL乐观锁控制电商并发下单扣减库存,在高并发下的问题

下订单减库存的方式 现在,连农村的大姐都会用手机上淘宝购物了,相信电商对大家已经非常熟悉了,如果熟悉电商开发的同学,就知道在买家下单购买商品的时候,是需要扣减库存的,当然有2种扣减库存的方式, 一种是预扣库存,相当于锁定库存, 一种是直接扣减库存. 我们采用的是预扣库存的方式,预扣库存的时候,在SalesInfo表中,将最大可售数量MaxSalesNum减去购买数量,用一条SQL语句来表示这个业务,就是下面这个样子的: update salesinfo set MaxSalesNum=MaxSa

ENode框架Conference案例分析系列之 - 订单处理减库存的设计

前言 前面的文章,我介绍了Conference案例的业务.上下文划分.领域模型.架构,以及代码整体流程.接下来想针对案例中一些重要的场景,分别做进一步的分析.本文想先介绍一下Conference案例的核心业务场景 - 订单处理减库存的设计. 下单以及订单处理流程描述 下单过程 预订者浏览某个已发布的会议: 进入会议的详情页面,该页面显示了所有可预订的座位分类信息: 预订者选择好要预订的座位分类,录入每个分类的预定数量: 预订者点击提交按钮,提交下单请求到Server端: Server端订单处理过

订单处理减库存的设计

订单处理减库存的设计 前言 前面的文章,我介绍了Conference案例的业务.上下文划分.领域模型.架构,以及代码整体流程.接下来想针对案例中一些重要的场景,分别做进一步的分析.本文想先介绍一下Conference案例的核心业务场景 - 订单处理减库存的设计. 下单以及订单处理流程描述 下单过程 预订者浏览某个已发布的会议: 进入会议的详情页面,该页面显示了所有可预订的座位分类信息: 预订者选择好要预订的座位分类,录入每个分类的预定数量: 预订者点击提交按钮,提交下单请求到Server端: S

mysql订单表如何设计?

mysql订单表如何设计? 商品表和订单表 . 通过一个表来关联. 那删除了商品,相关联的订单表如何显示出这个已经删除的商品? 订单表需要冗余商品名.商品编号.价格等基本信息. 不能只保存一个商品主键,这个是订单表的基本原则,同时生成了订单的商品是不能删除的. 订单表中引用商品表主键,删除使用状态假删. 同时引入商品的状态,总之就是反范式设计,保证一次可以获得全部要的状态,不要进行多表jion. 订单:  分为以下几种 订单凭证(接到客户的订单表),采购订单, 销售订单,委外订单 我的数据库 该

高并发核心技术 - 订单与库存

问题:一件商品只有100个库存,现在有1000或者更多的用户来购买,每个用户计划同时购买1个到几个不等商品.如何保证库存在高并发的场景下是安全的.1.不多发2.不少发 下单涉及的一些步骤1.下单2.下单同时预占库存3.支付4.支付成功真正减扣库存5.取消订单6.回退预占库存 什么时候进行预占库存方案一:加入购物车的时候去预占库存.方案二:下单的时候去预占库存.方案三:支付的时候去预占库存.分析:方案一:加入购物车并不代表用户一定会购买,如果这个时候开始预占库存,会导致想购买的无法加入购物车.而不

Java生鲜电商平台-高并发核心技术订单与库存实战

Java生鲜电商平台-高并发核心技术订单与库存实战 一. 问题 一件商品只有100个库存,现在有1000或者更多的用户来购买,每个用户计划同时购买1个到几个不等商品. 如何保证库存在高并发的场景下是安全的? (1)不多发 (2)不少发 二. 下单的步骤 (1)下单 (2)下单同时预占库存 (3)支付 (4)支付成功真正减扣库存 (5)取消订单 (6)回退预占库存 三. 什么时候进行预占库存? (1)方案一:加入购物车的时候去预占库存 (2)方案二:下单的时候去预占库存 (3)方案三:支付的时候去

Atitit. atiOrder   Order 订单管理框架的设计

Atitit. atiOrder   Order 订单管理框架的设计 1. Order 订单处理流程1 2. code2 3. Ref7 1. Order 订单处理流程 if(userSvr.isNotLogin()) { throw new RuntimeException(" not login 没登录,请先登录..#not_login"); } User u=userSvr.getLoginUser(); Acc a=accSvr.getAcc(u.id); BigDecimal

Oracle EBS-SQL (OM-3):销售连接停靠站时冲减库存出错处理.sql

DELETE FROM INV.MTL_RESERVATIONS MRWHERE EXISTS (SELECT 1 FROM WSH.WSH_DELIVERY_ASSIGNMENTS WDA                            ,WSH.WSH_DELIVERY_DETAILS    WDD                 WHERE WDA.DELIVERY_DETAIL_ID = WDD.DELIVERY_DETAIL_ID                     AND

订单系统 高级设计

ps 这里的高级设计是针对我自己的,一开始我设计的系统,虽然实现了mvc,但还没有真正做到逻辑分离. 因为之前开发过的订单已经已经上线,并且运营了一段时间,修正了很多的bug.这里给了我些思路.但我希望能够把他做的更好. 我把订单分为了3大块. 产品服务.订单服务.结算服务.用户服务 <?php interface IGoodsService { public function parseGoods(); } interface ICouponsService { public function