电商库存模型:占用、可用、在途、冻结的划分与落地
电商库存模型:占用、可用、在途、冻结的划分与落地
电商供应链里,库存不只是一串数字,而是多种「状态」的组合。把实物、占用、可用、在途、冻结五类拆清楚,并显式刻画它们之间的流转,才能避免超卖、少卖和对账困难。本文先说划分,再画流转,最后落库与一致性要点。
一、五类库存的定义与关系
以单 SKU、单仓库为维度,可抽象出五类数量(均为非负整数):
| 类型 | 含义 | 典型来源 |
|---|---|---|
| 实物库存 | 仓内实际可盘点的数量 | 采购入库、销售出库、调拨、盘点 |
| 占用库存 | 已成交未出库(订单已下单未发货) | 销售下单、预售确认 |
| 可用库存 | 可被新订单占用的数量 | 由公式算得,不单独持久 |
| 在途库存 | 已采购未入库 | 采购单下发、在途入库 |
| 冻结库存 | 被活动/调拨预占,尚未转成占用或出库 | 秒杀预占、仓间调拨预占 |
数量关系(核心公式):
1 | 可用库存 = 实物库存 - 占用库存 - 冻结库存 |
注意:在途不参与「可售」计算,只有入库后才变成实物,再通过可用被售卖;占用和冻结都是从「可用」里扣出来的,只是业务含义不同(前者是已卖,后者是预占)。
二、库存状态的流转(核心)
下面用「谁触发 → 哪些数量增减」的方式描述流转,便于对照落库与事件。
2.1 采购链路
1 | flowchart LR |
- 采购单确认:只在「在途」上 +N,不动实物与可用。
- 入库单完成:在途 -N,实物 +N;可用因公式自动增加(占用、冻结不变时)。
2.2 销售链路(正常下单 → 发货)
1 | flowchart LR |
- 下单:先扣可用(等价于占用增加),占用 +N;实物暂时不变,等出库再减。
- 出库:占用 -N、实物 -N;取消则只做「占用 -N」,可用通过公式回升。
2.3 订单取消
1 | flowchart LR |
只减占用,不碰实物;可用随公式恢复。
2.4 促销/秒杀预占(活动未开始)
1 | flowchart TB |
- 预占:把「可售」从可用挪到冻结,避免被普通订单卖光。
- 开卖:冻结减、占用加,进入正常销售链路。
- 取消/过期:只减冻结,可用通过公式恢复。
2.5 仓间调拨
1 | flowchart TB |
调出仓:先冻结再出库,避免调拨与销售抢同一批可用;调入仓可按「在途」建模(在途 +N 在调拨发运时,在途 -N、实物 +N 在入库时)。
2.6 流转总览(概念图)
1 | flowchart LR |
三、落地要点
3.1 表与字段设计(示意)
- 库存主表(按 仓库 + SKU):
physical_qty、occupied_qty、frozen_qty、in_transit_qty。 - 可用不落库,查询时算:
available_qty = physical_qty - occupied_qty - frozen_qty。 - 约束:
available_qty计算结果 ≥ 0;扣减可用时等价为「占用+」或「冻结+」,并做乐观锁或行锁,防止超卖。
3.2 扣减顺序与事务
- 下单占库存:在事务内「可用检查 → 占用+」或「实物 - 占用 - 冻结 ≥ 需求」后
occupied_qty += N。 - 出库:同一事务内「占用-」「实物-」;取消订单只「占用-」。
- 预占、释放、在途增减同理,保证一次业务操作内,涉及的多列增减原子完成。
3.3 流水与可追溯
每次数量变动落库存流水表:仓库、SKU、变动类型(占用+/-、冻结+/-、实物+/-、在途+/-)、变动量、单据号(订单号/采购单号/调拨单号等)、前后快照。便于对账、排查超卖和做审计。
3.4 与 DDD / 事件结合
- 聚合根:以「仓库+SKU」为库存聚合根,变更通过领域方法(如
reserve()、confirmOutbound())完成,内部维护五类数量。 - 跨上下文:出库完成可发「库存已扣减」领域事件,驱动订单侧更新发货状态;事件 payload 带单据号与数量,便于幂等与对账。
四、小结
- 五类:实物(仓内实有)、占用(已卖未发)、可用(公式)、在途(已采未入)、冻结(预占未用)。
- 关系:可用 = 实物 - 占用 - 冻结;在途独立,入库后才参与实物与可用。
- 流转:采购动在途与实物;销售动可用↔占用与实物;活动/调拨动可用↔冻结,再转占用或实物。
- 落地:主表存四类数量、可用计算得出;事务内原子增减;流水表记录每次变动;领域内封装变更并可选发事件,保证一致与可追溯。
把「划分 + 流转」在设计与代码里显式化,是库存准确、可解释、易扩展的基础。