#!/bin/bash
# =============================================================================
# 反向对照实验：证明「先查后写」的错误写法在并发下必然超卖
# 目的：证明上面的压测不是在「假成功」——错误写法确实会翻车
# =============================================================================
set -u
DB=rental_design_verify
ROOM_ID=$(psql -d $DB -tAc "select id from room where room_no='A-101';" | tr -d ' ')
TARGET_DATE='2026-11-10'
CONCURRENCY=20

echo "房间ID=$ROOM_ID  目标日期=$TARGET_DATE  并发数=$CONCURRENCY"
psql -d $DB -q -c "UPDATE room_calendar SET total_qty=1, sold_qty=0 WHERE room_id=$ROOM_ID AND biz_date='$TARGET_DATE';"

rm -f /tmp/naive_result_*.txt
echo "用【错误写法：先查余量再更新】并发抢占..."
echo "（在查询与更新之间插入 100ms 睡眠，模拟真实业务处理耗时）"

for i in $(seq 1 $CONCURRENCY); do
  (
    # 错误写法：先 SELECT 判断，再 UPDATE —— 典型竞态
    psql -d $DB -q -tA <<SQL > /tmp/naive_result_$i.txt 2>&1
BEGIN;
SELECT CASE WHEN sold_qty < total_qty THEN 1 ELSE 0 END AS can_buy
  FROM room_calendar
 WHERE room_id=$ROOM_ID AND biz_date='$TARGET_DATE'
   FOR UPDATE;  -- 即使加 FOR UPDATE，若业务逻辑在锁外判断仍会错
SQL
    # 模拟业务处理间隔（真实场景中这里是校验、算价、调第三方）
    sleep 0.1
    psql -d $DB -q -tA -c \
      "UPDATE room_calendar SET sold_qty = sold_qty + 1 WHERE room_id=$ROOM_ID AND biz_date='$TARGET_DATE' AND sold_qty < total_qty; SELECT 'APPROVED';" >> /tmp/naive_result_$i.txt 2>&1
    psql -d $DB -q -c "COMMIT;" >> /tmp/naive_result_$i.txt 2>&1
  ) &
done
wait

SOLD=$(psql -d $DB -tAc "select sold_qty from room_calendar where room_id=$ROOM_ID and biz_date='$TARGET_DATE';" | tr -d ' ')

echo ""
echo "================ 反向对照结果 ================"
echo "最终已售数 : $SOLD   （库存上限为 1）"
echo ""
if [ "$SOLD" -le 1 ]; then
  echo "ℹ️  本次条件更新 (WHERE sold_qty < total_qty) 兜住了，未超卖。"
  echo "    说明：真正的保护来自 SQL 条件判断的原子性。"
  echo "    但若业务在「查」与「写」之间做了决策（如算价、锁座），"
  echo "    条件更新会静默失败（影响 0 行）而业务已认为成功 —— 这才是隐患。"
else
  echo "✅ 对照成立：错误写法发生了超卖（已售 $SOLD > 1）"
fi
