库存一致性排查手册
本文用于处理“列表有库存但下单失败”“库存流水和实时库存不一致”“报表库存和业务库存不一致”等问题。库存问题不要只看一个表,必须同时看商品、仓库、货位、流水、实时库存、缓存和报表口径。
适用场景
- 采购/秒杀/销售页面显示有库存,但加购或出库提示库存不足。
- 采购入库、销售出库、退货入库后实时库存没变化。
- 库存流水有记录,但
t_scm_inventory_real_time数量不对。 - 业务库存和报表库存不一致。
- 指定仓、供给仓、服务站仓口径混淆。
入口文件
- 库存服务:
application/Services/Storage/InventorySer.php - 库存查询:
application/Services/Storage/InventoryQuerySer.php - 仓库服务:
application/Services/Storage/StorageSer.php - 套包库存:
application/Services/Storage/PackageSer.php - 采购入库:
application/controllers/scm/InvPu.php - 销售出库:
application/controllers/scm/InvSa.php - 盘点:
application/controllers/inner/gpda/TakeStock.php - 库存任务:
application/controllers/tasks/GoodsCache.php、GoodsEsCache.php、UpdateEsGoodsInfo.php
核心表
- 商品:
t_bs_goods、t_bs_goods_ext、t_bs_goods_sto - 仓库:
t_bs_storage、t_bs_storage_location - 货位:
t_bs_storage_area、t_bs_storage_area_rel - 库存流水:
t_scm_inventory、t_scm_inventory_info - 往月流水:
th_scm_inventory - 实时库存:
t_scm_inventory_real_time - 盘点:
t_scm_inventory_check、t_scm_inventory_check_info - 库存预警:
t_scm_inventory_warning
状态和枚举
TransTypeEnums.php是库存方向的核心字典。- 增加库存:采购入库
150501、销售退货入库150502、其他入库150706、盘盈150701、套包入库。 - 减少库存:销售出库
150601、采购退货170402、其他出库150806、盘亏150801、套包出库。 - 盘点:
180510。
主流程排查
- 确认商品口径。
- 明确页面或接口用的是
skuId、invId还是商品编码。 - 查商品是否启用、是否套包、是否有销售/采购限制、是否存在编码合并。
- 确认仓库口径。
- 普通服务站仓、指定仓、供给仓、微仓、周转仓不要混用。
- 秒杀活动还要看库存范围:服务站对应仓、指定仓、全局预留。
- 查实时库存。
- 按
sid + invId/skuId + storageId + areaId查t_scm_inventory_real_time。 - 如果页面聚合展示,确认是否包含多个货位、多个仓库。
- 查库存流水。
- 按业务单号查
t_scm_inventory。 - 按库存主表 id 查
t_scm_inventory_info。 - 对同一个商品汇总流水方向,和实时库存变化对比。
- 查业务单据。
- 采购入库看
t_scm_pu_invoice_info。 - 销售出库看
t_scm_sa_invoice_info。 - 采购退货/销售退货看对应退货单和关闭记录。
- 秒杀看活动商品锁定量、已用量和采购单。
- 查缓存和索引。
- 商品搜索可能走 ES 或物料缓存。
- 服务站物料缓存可能未刷新,导致列表展示旧库存或旧状态。
- Redis/Mongo/ES 只作为展示或查询加速,最终库存以业务库流水和实时库存为准。
- 查报表口径。
- 报表可能走业务库汇总、历史归档或 Hologres/DWD。
- 当天实时业务和离线报表存在延迟是常见现象。
常见问题判断
| 现象 | 优先检查 | | --- | --- | | 列表有库存,加购失败 | 列表仓库口径、服务站黑白名单、活动库存范围、实时库存货位 | | 出库失败提示不足 | 销售明细未出库数量、实时库存、货位选择、冻结/锁定逻辑 | | 入库成功但库存没加 | 入库单是否生成库存流水、InventorySer::save/changeInventoryQty 是否执行 | | 流水有但实时库存不对 | 是否重复写流水、实时库存更新失败、分表/月份归档查询错 | | 报表库存和业务不一致 | 报表同步延迟、查询条件、历史表和当月表合并口径 |
常用 SQL 模板
-- 实时库存
select * from t_scm_inventory_real_time
where sid = :sid and invId = :inv_id;
-- 按业务单号查库存流水
select * from t_scm_inventory
where sid = :sid and srcBillNo = :bill_no;
-- 查流水明细
select * from t_scm_inventory_info
where sid = :sid and inventoryId = :inventory_id;
-- 查仓库和货位
select * from t_bs_storage where sid = :sid;
select * from t_bs_storage_area where sid = :sid and storageId = :storage_id;
常用 rg 命令
rg -n "function save|changeInventoryQty|SCM_INVENTORY_REAL_TIME" application/Services/Storage application/service
rg -n "TRANSTYPE_PU_PURCHASE|TRANSTYPE_SA_INVOICE_SALE|TRANSTYPE_OI_LOSS" application/KzData/Enums/TransTypeEnums.php
rg -n "MaterielCache|GoodsEsCache|UpdateEsGoodsInfo|redis|Mongo|EsSer" application/Services application/controllers/tasks
rg -n "stock_qty|supply_stock_qty|locked_qty|used_qty" application/Services application/controllers
改动风险和回归清单
- 任意库存写入改动,都要回归采购入库、销售出库、销售退货、采购退货、盘点、调拨。
- 任意库存查询改动,都要回归普通商品、套包、指定仓、服务站仓、活动商品。
- 任意缓存改动,都要回归商品列表、活动列表、加购、确认页、库存报表。
- 修数据时先备份原始记录,优先补业务流水,不要只改实时库存结果表。