Files
wms-saas/docs/05-inventory.md
T
2026-09-29 13:08:21 +08:00

2.0 KiB
Raw Blame History

05 库存设计

库存设计是整个 WMS 的核心。

库存模型

不要简单设计 sku + warehouse + quantity,必须建立完整库存模型。

数量维度

字段 含义
available_qty 可用数量
reserved_qty 预占 / 锁定数量
picked_qty 已拣货数量
hold_qty 冻结数量
damaged_qty 残损数量
in_transit_qty 在途数量

位置与属性维度

  • 仓库
  • 库区
  • 库位
  • SKU
  • 批次
  • 库存状态

核心关系

SKU
 ↓
Warehouse
 ↓
Zone
 ↓
Location
 ↓
Batch
 ↓
Inventory

库存流水必须是核心数据

必须设计 wms_stock_log,任何库存变化必须能够追溯。例如:

入库 +100
锁定 -20
拣货 -5
出库 -5
盘点 +2
调整 -1

需要能够回答:为什么这个 SKU 的库存从昨天的 100 变成今天的 76?

  • 库存余额是结果。
  • 库存流水是事实。

不要只修改 inventory.quantity 而不留下完整流水。库存余额更新与流水写入必须在同一事务中完成,流水需记录业务单据类型与单号(如 inbound_no / outbound_no)。

库存并发安全

库存扣减必须考虑并发。

禁止: 先 SELECT → PHP 计算 → UPDATE。这种方式容易产生超卖。

根据实际业务采用:

  • 数据库事务
  • 行锁(SELECT ... FOR UPDATE)
  • 乐观锁(version 字段)
  • 原子更新
  • Redis 分布式锁(必要时)

原子更新示例:

UPDATE wms_inventory
SET available_qty = available_qty - :qty,
    reserved_qty  = reserved_qty + :qty
WHERE tenant_code = :tenant_code
  AND id = :id
  AND available_qty >= :qty;
-- 受影响行数为 0 即库存不足,必须抛出业务异常

必须保证:

  • available_qty >= 扣减数量
  • 多个并发请求不能导致负库存或重复扣减

并发验收用例

两个请求同时扣减 8 个库存,而实际只有 10 个库存。必须保证:

  • 不会出现 available_qty = -6
  • 不能出现两个订单都成功扣减 8