Skip to content
Back to skills

Inventory Occupy

ASecurity

Use when deciding 下单扣库存 vs 支付扣库存 vs 预占/锁定库存, 可售库存, 锁定库存, occupy TTL. Do not replace the SQL condition stock>=n (backend-concurrency-sell). Do not use for 秒杀分层 (backend-seckill).

  • 2 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 3, 2026
ai-agentssqlbackend

Security analysis

A100/100

Scanned September 3, 2026

npx -y skills add 1398281322-a11y/java-backend-guardrails --skill inventory-occupy --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Inventory Occupy?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Inventory Occupy
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/1398281322-a11y-inventory-occupy/badge)](https://www.skillsdirectory.com/skills/1398281322-a11y-inventory-occupy)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: inventory-occupy
description: Use when deciding 下单扣库存 vs 支付扣库存 vs 预占/锁定库存, 可售库存, 锁定库存, occupy TTL. Do not replace the SQL condition stock>=n (backend-concurrency-sell). Do not use for 秒杀分层 (backend-seckill).
---

# 库存预占 / 扣减时机

## When to Invoke

面试问「库存什么时候扣」、下单占库存支付才确认、超时释放、可售=总-锁-售。电商/票务/酒店都是这个模型。

## When NOT

已经确定「一行 stock 条件扣」的实现细节 → `concurrency-sell`。秒杀分层 → `seckill`。售后回库存 → `refund-aftersale`。

## 风险(面试考点)

三种时机:

| 时机 | 优点 | 坑 |
|------|------|-----|
| 下单扣 | 支付时一定有货 | 未支付占死库存,必须超时释放 |
| 支付扣 | 不占库存 | 支付成功可能无货,要赔/取消 |
| 预占(锁定) | 可售与占用分开 | 字段多,超时释放要幂等 |

面试没有唯一答案。零售电商默认 **下单预占 + 超时释放 + 支付确认**;秒杀常用 Redis 预扣再异步下单(`seckill`)。

「先查库存再扣」不是预占,那是丢失更新。预占必须是一条条件更新或 Lua。

## 方案选型(轻量优先)

文旅门票/核销名额:与电商下单预占相同,`CLOSED` 时释放。

字段(推荐预占模型):

```text
total / locked / sold
available = total - locked - sold
下单:locked += n  WHERE available >= n
支付:locked -= n, sold += n  WHERE locked >= n
取消:locked -= n  WHERE locked >= n
```

或单字段 `stock` 当可售:下单直接减,取消再加。简单,但「已售」靠订单汇总。

## 默认方案

```sql
-- 预占
UPDATE sku SET locked = locked + #{n}
WHERE sku_id = #{id} AND (total - locked - sold) >= #{n};

-- 支付确认
UPDATE sku SET locked = locked - #{n}, sold = sold + #{n}
WHERE sku_id = #{id} AND locked >= #{n};

-- 关单释放(只能释放本单占用量,用流水防多释放)
```

占用来源记 `t_stock_log(order_no, sku_id, n, type)`,`uk(order_no, sku_id, type)`。释放/确认都插流水,重复空操作。

超时释放走 `delay-job`,不要扫全表 locked>0。

## 反例

错误:支付扣库存,回调成功才发现 stock=0,订单 PAID 无货。
正确:要嘛预占,要嘛支付失败/赔付流程写清。

错误:关单 `stock=stock+n` 无流水,MQ 重试加两次。
正确:释放流水唯一键。

错误:预占用分布式锁包读改写。
正确:一条条件 UPDATE。

## 验证

- 库存 1,两单同时下,只有一单预占成功。
- 预占后关单,可售回到 1,只回一次。
- 支付确认后 locked 下降、sold 上升,总和不变。

## 评审清单

- [ ] 扣减时机写进方案,不是默认「反正会扣」
- [ ] 预占/释放有流水唯一键
- [ ] 超时释放不扫全表
---

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.