
CASE C28-01 :: 正常路径：预留、同键重放、确认、按 request_key 查询
  ok   首次预留 (expected=HELD, actual=HELD)
  ok   同一 request_key 重放 (expected=REPLAY, actual=REPLAY)
  ok   重放返回同一预留 (expected=1, actual=1)
  ok   库存只扣一次 (expected=2, actual=2)
  ok   同键不同用户被拒绝 (expected=KEY_REUSED, actual=KEY_REUSED)
  ok   未到期的 HELD 可以确认
  ok   重复确认不再迁移
  ok   查询状态 (expected=CONFIRMED, actual=CONFIRMED)
  ok   已确认的预留不能被取消归还 (expected=0, actual=0)
  ok   守恒 total-available-active (expected=0, actual=0)

CASE C28-02 :: 准入边界：上限 2、排队位 1；排满即拒、等待超时、等待后进入
  ok   第 1 个直接进入 (expected=ADMITTED, actual=ADMITTED)
  ok   第 2 个直接进入 (expected=ADMITTED, actual=ADMITTED)
  ok   排队位已满时第 4 个立即拒绝 (expected=REJECTED_QUEUE_FULL, actual=REJECTED_QUEUE_FULL)
  ok   无人退出时等待者超时被拒 (expected=REJECTED_WAIT_TIMEOUT, actual=REJECTED_WAIT_TIMEOUT)
  ok   有人退出后等待者进入 (expected=ADMITTED_AFTER_WAIT, actual=ADMITTED_AFTER_WAIT)
  ok   全部退出后重新可进入 (expected=ADMITTED, actual=ADMITTED)
  note counters admitted=3 admitted_after_wait=1 rejected_queue_full=1 rejected_wait_timeout=1 max_in_flight=2 max_waiting=1
  ok   同时在内的请求从未超过上限 (expected=2, actual=2)

CASE C28-03 :: 超额并发：150 个线程争 40 件，单热点行条件扣减
  note outcomes {HELD=40, SOLD_OUT=110}
  ok   成功数等于库存 (expected=40, actual=40)
  ok   其余全部售罄 (expected=110, actual=110)
  ok   最终库存 0 (expected=0, actual=0)
  ok   有效预留 40 行 (expected=40, actual=40)
  ok   守恒 (expected=0, actual=0)
  note COUNT C28-03 success=40 sold_out=110 final_available=0

CASE C28-04 :: 重复：16 线程同一 request_key；8 线程同一用户不同 key
  note same key {HELD=1, REPLAY=15} ; same user {HELD=1, USER_LIMIT=7}
  ok   同键只有一个 HELD (expected=1, actual=1)
  ok   其余 15 个是 REPLAY (expected=15, actual=15)
  ok   同用户只有一个 HELD (expected=1, actual=1)
  ok   其余 7 个撞上部分唯一索引 (expected=7, actual=7)
  ok   库存只扣 2 件 (expected=8, actual=8)
  ok   释放后同一用户可以再次预留 (expected=HELD, actual=HELD)
  ok   守恒 (expected=0, actual=0)

CASE C28-05 :: HTTP 过载：120 个客户端同时到达，准入上限 4、排队位 8、等待 400ms、处理 30ms，库存 30；收到 503 的客户端用同一 request_key 退避重试，直到得到 201 或 409
  note final http codes {201=30, 409=90} first_try_503=108 all_503=829
  note admission admitted=20 admitted_after_wait=100 rejected_queue_full=829 rejected_wait_timeout=0 max_in_flight=4 max_waiting=8
  ok   每个客户端最终得到 201 或 409 (expected=0, actual=0)
  ok   最终成功数等于库存 30 (expected=30, actual=30)
  ok   其余 90 个得到售罄 (expected=90, actual=90)
  ok   503 次数等于准入拒绝计数 (expected=829, actual=829)
  ok   被准入的请求恰好 120 次（每个客户端一次） (expected=120, actual=120)
  ok   同时处理数不超过 4（实际 4）
  ok   同时等待数不超过 8（实际 8）
  ok   首轮过载时确有快速拒绝
  ok   确有请求在等待后进入
  ok   库中有效预留 30 行 (expected=30, actual=30)
  ok   最终库存 0 (expected=0, actual=0)
  ok   守恒 (expected=0, actual=0)
  note COUNT C28-05 success=30 sold_out=90 rejected_503=829 admitted_after_wait=100 final_available=0 (rejected/wait counts depend on scheduling)

CASE C28-06 :: 客户端断开：请求发出 100ms 后关闭连接，服务端处理需 600ms
  note query right after disconnect: status=NOT_FOUND
  ok   断开后服务端照常完成，凭 request_key 查到 HELD (expected=status=HELD, actual=status=HELD)
  ok   服务端完整处理了 1 次 (expected=1, actual=1)
  ok   客户端用同一 request_key 重试得到 200 (expected=200, actual=200)
  ok   重试结果是 REPLAY：outcome=REPLAY reservation=1 status=HELD
  ok   库存只扣 1 件 (expected=4, actual=4)
  ok   守恒 (expected=0, actual=0)
  ok   缺少 request_key 的请求被拒绝 (expected=400, actual=400)

CASE C28-07 :: 到期释放：20 个 HELD 中 8 个到期；释放执行一次、重放一次、4 线程并发重放
  ok   第一次释放归还 8 件 (expected=8, actual=8)
  ok   立即重放归还 0 件 (expected=0, actual=0)
  ok   4 线程并发重放合计归还 0 件 (expected=0, actual=0)
  ok   剩余 12 个到期后由 4 线程并发释放，合计恰好归还 12 件 (expected=12, actual=12)
  ok   库存全部回到 20 (expected=20, actual=20)
  note status {EXPIRED=20}
  ok   守恒 (expected=0, actual=0)

CASE C28-08 :: 确认与到期释放竞争：40 个已到期 HELD，确认线程与释放线程同时处理
  note confirmed=33 returned=7 status {CONFIRMED=33, EXPIRED=7}
  ok   每个预留恰好被一方处理 (expected=40, actual=40)
  ok   归还件数等于 EXPIRED 行数 (expected=7, actual=7)
  ok   库存只为 EXPIRED 行归还 (expected=7, actual=7)
  ok   守恒 (expected=0, actual=0)

CASE C28-09 :: 多进程：原子释放任务在提交前被 kill -9，再重放两次
  note worker pid=2340875 says: STAGE uncommitted returned=5
  ok   子进程已执行释放语句但未提交 (expected=STAGE uncommitted returned=5, actual=STAGE uncommitted returned=5)
  ok   未提交时外部看不到归还 (expected=0, actual=0)
  ok   子进程被 SIGKILL 终止（退出码 128+9） (expected=137, actual=137)
  ok   数据库回滚未提交事务，5 个到期预留仍是 HELD (expected=5, actual=5)
  ok   库存没有被归还 (expected=0, actual=0)
  ok   重放：归还 5 件 (expected=5, actual=5)
  ok   再次重放：归还 0 件 (expected=0, actual=0)
  note COUNT C28-09 extra_success=5 active=10 total=10
  ok   10 个补抢请求只有 5 个成功 (expected=5, actual=5)
  ok   有效预留 10，不超过库存 (expected=10, actual=10)
  ok   守恒 (expected=0, actual=0)

CASE C28-10 :: 负向对照：释放不检查状态、无条件归还，重放后补抢
  note after replay available=10 active=5
  note COUNT C28-10 extra_success=10 active=15 total=10
  ok   negative control exposes: 有效预留 15 超过库存 10（超卖）
  ok   negative control exposes: 守恒检查发现偏差 -5

CASE C28-11 :: 负向对照（多进程）：先归还库存并提交、再改状态；两步之间 kill -9，重放后补抢
  note worker pid=2340903 says: STAGE stock-returned returned=5
  ok   子进程已提交归还、尚未改状态 (expected=STAGE stock-returned returned=5, actual=STAGE stock-returned returned=5)
  ok   子进程被 SIGKILL 终止 (expected=137, actual=137)
  note replay worker says: STAGE stock-returned returned=5
  note replay worker says: STAGE status-updated
  ok   重放进程正常结束 (expected=0, actual=0)
  note COUNT C28-11 extra_success=10 active=15 total=10
  ok   negative control exposes: 有效预留 15 超过库存 10（超卖）

CASE C28-12 :: 负向对照：先查该用户有无有效预留再插入，无部分唯一索引
  ok   negative control exposes: 同一用户出现 2 个有效预留
  ok   对照组：有部分唯一索引时只有 1 个 HELD (expected=1, actual=1)
  ok   对照组：另一个得到 USER_LIMIT (expected=1, actual=1)

CASE C28-13 :: 方案比较：同一输入（120 线程、40 件、每人一次）下 A 热点行 / B 名额行 SKIP LOCKED / C 内存先扣
  ok   A 守恒 (expected=0, actual=0)
  note COUNT C28-13 A success=40 left=0
  note COUNT C28-13 B success=40 no_slot=80 left=0 distinct_holders=40
  note COUNT C28-13 C success=40 ledger_rows=40 mem_left=0
  ok   A 成功 40 (expected=40, actual=40)
  ok   B 成功 40 (expected=40, actual=40)
  ok   B 每个名额行最多一个持有者 (expected=40, actual=40)
  ok   C 正常运行时成功 40 (expected=40, actual=40)
  ok   C 销售记录 40 行 (expected=40, actual=40)

CASE C28-14 :: 边界：未提交的占用使 B 跳过名额行而报“无名额”，A 则等待后成功
  ok   t1 占用 1 号名额（未提交）
  ok   t2 跳过被锁的 1 号，占用 2 号
  ok   t3 看不到可锁的空名额，返回无名额
  ok   t1 回滚后实际还剩 1 个名额 (expected=1, actual=1)
  ok   A：t1 预留最后 1 件（未提交，持有热点行锁） (expected=HELD, actual=HELD)
  ok   A：t3 在等待 t1 的行锁，没有提前返回售罄
  ok   A：t1 回滚后 t3 按最新行版本重新判断并成功 (expected=HELD, actual=HELD)
  ok   A 守恒 (expected=0, actual=0)

CASE C28-15 :: 负向对照：方案 C 节点重启按配置份额重置计数，对账发现超卖；按落库记录重算则不超卖
  ok   重启前售出 40 (expected=40, actual=40)
  note COUNT C28-15 extra_after_restart=20 ledger_rows=60 total=40
  ok   negative control exposes: 对账：销售记录 60 行超过库存 40
  ok   按落库记录重算后重启不再多卖 (expected=0, actual=0)
  ok   node-1 销售记录仍为份额 20 (expected=20, actual=20)

SUMMARY passed=95 failed=0
