结论:WMS里库存数量不要直接改,正确做法是“每一次出入库只写一条流水,余额由流水累计得到”,同时保留一张余额表用于快速查询。这样账实不符时才能逐笔回溯,而不是对着一个被改过的数字猜原因。
一、为什么不能直接改库存数量
最常见的设计是一张库存表,入库就加、出库就减。问题在于:出现差异时没有历史,无法判断是重复扫码、漏扫、还是并发覆盖。双表设计把“结果”和“过程”分开:流水表只增不改,余额表是流水汇总后的快照。
二、两张表的关键字段
库存流水表 inv_txn:关键字段 txn_id、txn_no(业务唯一号)、txn_type、material_code、batch_no、location_code、qty_change、ref_doc_no、operator、txn_time;只追加,不删除不修改,冲销用反向流水。
库存余额表 inv_balance:关键字段 material_code、batch_no、location_code、qty_on_hand、qty_locked、updated_at;唯一索引(物料+批次+库位),数量由事务内原子更新。
三、写入流程
1. 接口先按 txn_no 做唯一性检查,防止重复扫码或重试造成重复入账。
2. 在同一个数据库事务内:插入一条流水,并对余额表做带条件的原子更新(qty_on_hand = qty_on_hand + 变化量,条件是更新后不小于0);更新行数为0表示库存不足,整个事务回滚。
3. 锁定数量单独用 qty_locked 字段,拣货分配时先锁定,出库确认时再同时扣减 qty_on_hand 与 qty_locked。
4. 冲销、盘点调整都走同一流程,txn_type 区分为入库、出库、移库、盘盈、盘亏、冲销。
四、盘点与对账
每日或定期按物料、批次、库位对流水的变化量求和,与余额表比对,不一致的进入异常清单。盘点差异不直接改余额,而是生成盘盈或盘亏流水,并记录盘点单号与审批人。
五、常见追问
流水表会不会太大?按月分区,历史数据归档,余额表保持小而快。
移库怎么记?一条移库拆成同一事务内的两条流水(源库位减、目标库位加),共用同一个 txn_no 前缀。
先进先出怎么实现?拣货时按批次入库时间升序分配批次,分配结果落到流水的批次字段上。
并发下会不会超卖?依靠带条件的原子更新,不要先查后改。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70051529/viewspace-3186756/ ,如需转载,请注明出处,否则将追究法律责任。