这个问题最容易被“后台数量还有几十个”带偏。Magento 2.3 以后用了 MSI,页面上的 Source Item 数量并不等于前台可售数量。真正参与加购判断的是库存、来源分配、缺货阈值和 reservation 共同计算出来的 salable quantity。
先让Magento自己报出可售数量
不要只查 inventory_source_item.quantity。先运行:
php bin/magento inventory:reservation:list-inconsistencies -r再用 SKU 查可售数量。不同版本可用的 CLI 命令并不完全一致,我一般直接在一个临时 PHP 脚本里调用 GetProductSalableQtyInterface,并明确传入当前 website 对应的 stock ID。这样能避免查错库存范围。
数量有货但salable为0,就逐项对账
我会按这个顺序看:
- 当前 Website 是否真的分配到了这个 Stock。
- Stock 下是否包含保存该 SKU 的 Source。
- Source Item 的状态是不是
In Stock,不是只看 quantity。 Out-of-Stock Threshold是否大于或等于现有数量。inventory_reservation里是否残留了没有补偿回来的负数。
查 reservation:
SELECT stock_id, sku, SUM(quantity) AS reserved
FROM inventory_reservation
WHERE sku = 'TEST-SKU'
GROUP BY stock_id, sku;不要直接删表里的 reservation。先用 list-inconsistencies 找异常订单,再生成补偿:
php bin/magento inventory:reservation:list-inconsistencies -r |
php bin/magento inventory:reservation:create-compensations处理完重新索引 inventory,再用同一 website、同一 SKU 查询 salable quantity。只有接口返回值恢复并且前台实际能加入购物车,才说明不是表面上“改了库存”,而是可售库存链路真的恢复了。

