linlinjava/litemall · error · RuntimeException
商品货品库存增加失败
Error message
商品货品库存增加失败
What it means
In WxOrderService.cancel, after the order is successfully flipped to STATUS_CANCEL, the service restores inventory by calling productService.addStock(productId, number) for each order-goods row. addStock maps to a conditional SQL UPDATE (litemall_goods_product SET number = number + ?); 0 affected rows means the product row was not matched — typically the SKU was logically deleted or its id no longer resolves — and the service throws '商品货品库存增加失败' (stock restore failed). Because this runs after the status update within the same flow, the surrounding transaction must roll everything back, leaving the order un-cancelled.
Source
Thrown at litemall-wx-api/src/main/java/org/linlinjava/litemall/wx/service/WxOrderService.java:587
OrderHandleOption handleOption = OrderUtil.build(order);
if (!handleOption.isCancel()) {
return ResponseUtil.fail(ORDER_INVALID_OPERATION, "订单不能取消");
}
// 设置订单已取消状态
order.setOrderStatus(OrderUtil.STATUS_CANCEL);
order.setEndTime(LocalDateTime.now());
if (orderService.updateWithOptimisticLocker(order) == 0) {
throw new RuntimeException("更新数据已失效");
}
// 商品货品数量增加
List<LitemallOrderGoods> orderGoodsList = orderGoodsService.queryByOid(orderId);
for (LitemallOrderGoods orderGoods : orderGoodsList) {
Integer productId = orderGoods.getProductId();
Short number = orderGoods.getNumber();
if (productService.addStock(productId, number) == 0) {
throw new RuntimeException("商品货品库存增加失败");
}
}
// 返还优惠券
releaseCoupon(orderId);
return ResponseUtil.ok();
}
/**
* 付款订单的预支付会话标识
* <p>
* 1. 检测当前订单是否能够付款
* 2. 微信商户平台返回支付订单ID
* 3. 设置订单付款状态
*
* @param userId 用户ID
* @param body 订单信息,{ orderId:xxx }View on GitHub (pinned to a1ef964a71)
Solutions
- Check whether the 0-row result is due to logical delete of the SKU: if the row is gone for good, decide business-wise whether to skip restoring stock for that line (log it) instead of failing the whole cancel.
- If the cancel must succeed, wrap addStock per-item, log failures with productId, and continue — stock drift on a dead SKU is usually acceptable; order state consistency is not.
- Investigate the data: SELECT deleted, number FROM litemall_goods_product WHERE id=<productId> for each order_goods row of the failing order; fix orphaned references or re-create the SKU row.
Example fix
// before
if (productService.addStock(productId, number) == 0) {
throw new RuntimeException("商品货品库存增加失败");
}
// after - log and continue so cancellation is not blocked by a dead SKU
if (productService.addStock(productId, number) == 0) {
logger.error("库存返还失败, 货品不存在或已删除, productId={}, orderId={}", productId, orderId);
} Defensive patterns
Strategy: fallback
Validate before calling
// optional pre-check: identify dead SKUs before cancelling
List<LitemallOrderGoods> goods = orderGoodsService.queryByOid(orderId);
for (LitemallOrderGoods og : goods) {
if (productService.findById(og.getProductId()) == null) {
logger.warn("订单{}包含已删除货品{},取消时将跳过库存返还", orderId, og.getProductId());
}
} Try / catch
for (LitemallOrderGoods orderGoods : orderGoodsList) {
if (productService.addStock(orderGoods.getProductId(), orderGoods.getNumber()) == 0) {
// dead SKU: log and continue — do not block the cancellation
logger.error("库存返还失败 productId={} orderId={}", orderGoods.getProductId(), orderId);
}
} Prevention
- Decide explicitly whether a missing SKU should block cancellation; in most domains order-state consistency outranks stock restoration for deleted products.
- Never hard-delete product rows that historical orders reference — use the logical deleted flag the conditional UPDATE already respects.
When it happens
Trigger: An order contains a product SKU that has since been logically deleted (deleted=1) or hard-removed by an admin; the order_goods row references a productId that no longer exists in litemall_goods_product (data drift from manual edits/imports). The cancel itself succeeds but the very first addStock UPDATE matches 0 rows.
Common situations: Admin deletes obsolete SKUs while old unshipped orders for them still exist; store data migrated/pruned without preserving product ids; test databases with order_goods rows referencing seeded products that were wiped.
Related errors
AI-assisted analysis of linlinjava/litemall@a1ef964a71 (2026-08-14).
Data as JSON: /api/errors/a7d6b165a3fd2274.
Report an issue: GitHub.