yudaocode/SpringBoot-Labs · error · java.lang.Exception

库存不足

Error message

库存不足

What it means

Thrown by the product service of labx-17's Seata AT + Feign demo. reduceStock runs a conditional stock decrement; a 0-row update means insufficient stock and the code throws at line 34. The exception travels back through the Feign interface to the order service and rolls back the Seata global transaction, restoring the order and account branches.

Source

Thrown at labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-product-service/src/main/java/cn/iocoder/springcloud/labx17/productservice/service/impl/ProductServiceImpl.java:34

    @Autowired
    private ProductDao productDao;

    @Override
    @Transactional // 开启新事物
    public void reduceStock(Long productId, Integer amount) throws Exception {
        logger.info("[reduceStock] 当前 XID: {}", RootContext.getXID());

        // 检查库存
        checkStock(productId, amount);

        logger.info("[reduceStock] 开始扣减 {} 库存", productId);
        // 扣减库存
        int updateCount = productDao.reduceStock(productId, amount);
        // 扣除成功
        if (updateCount == 0) {
            logger.warn("[reduceStock] 扣除 {} 库存失败", productId);
            throw new Exception("库存不足");
        }
        // 扣除失败
        logger.info("[reduceStock] 扣除 {} 库存成功", productId);
    }

    private void checkStock(Long productId, Integer requiredAmount) throws Exception {
        logger.info("[checkStock] 检查 {} 库存", productId);
        Integer stock = productDao.getStock(productId);
        if (stock < requiredAmount) {
            logger.warn("[checkStock] {} 库存不足,当前库存: {}", productId, stock);
            throw new Exception("库存不足");
        }
    }

}

View on GitHub (pinned to 6c12efaed0)

Solutions

  1. Reset product stock via the lab's SQL or an UPDATE statement.
  2. Retry with a smaller amount.
  3. Treat this as the business outcome: return an 'out of stock' response to the caller instead of a raw exception.

Example fix

// before
int updateCount = productDao.reduceStock(productId, amount);
if (updateCount == 0) {
    throw new Exception("库存不足");
}

// after — domain exception; the SQL guard stays authoritative
int updateCount = productDao.reduceStock(productId, amount);
if (updateCount == 0) {
    throw new OutOfStockException(productId, amount);
}
Defensive patterns

Strategy: validation

Validate before calling

Integer stock = productFeign.getStock(productId);
if (stock == null || stock < amount) {
    return Result.error("库存不足");
}

Try / catch

try {
    orderService.create(userId, productId, amount);
} catch (Exception e) {
    if (e.getMessage() != null && e.getMessage().contains("库存不足")) {
        return ResponseEntity.badRequest().body("out of stock");
    }
    throw e;
}

Prevention

When it happens

Trigger: Order amount greater than remaining stock at UPDATE time — typically after the pre-check passed but stock changed concurrently, or when the seeded stock is simply too low for the requested amount.

Common situations: Repeated demo orders drained product.stock without reseeding; concurrent purchases of the final stock; amount parameter confusion (count vs total price) between services.

Related errors


AI-assisted analysis of yudaocode/SpringBoot-Labs@6c12efaed0 (2026-08-14). Data as JSON: /api/errors/2729fa7aaf0751ca. Report an issue: GitHub.