---
name: concurrency-control
when: '并发控制, 并发, 锁, 乐观锁, 悲观锁, 分布式锁, 竞态条件, 超卖, 库存扣减, 重复提交, 原子操作, 幂等, 去重'
scope:
  - backend
products:
  - '*'
id: ka-pattern-concurrency-control
asset_kind: pattern
lifecycle_status: active
owner_mechanism_id: mc-backend-pattern
authority: supporting
routes:
  - '*'
primary_triggers:
  - 并发控制
  - 并发
  - 锁
  - 乐观锁
  - 悲观锁
  - 分布式锁
  - 竞态条件
  - 超卖
  - 库存扣减
  - 重复提交
  - 原子操作
  - 幂等
  - 去重
priority: P2
specificity: 3
version: 1.1.0
last_reviewed: '2026-06-01'
consumes: []
emits: []
secondary_triggers: []
negative_triggers: []
type: pattern
stages: ["编码与单元测试", "架构设计"]
---

## 决策规则
- 涉及金额、库存、配额、计数器等可变共享状态的操作必须显式声明并发控制策略
- 乐观锁适用于读多写少场景（版本号字段 + CAS），悲观锁适用于写多竞争激烈场景（SELECT FOR UPDATE）
- 分布式环境必须使用分布式锁（Redis SETNX / Redisson / ZooKeeper），禁止依赖 JVM 级锁跨实例
- 锁粒度必须最小化：锁具体资源而非整个表，锁业务 ID 而非全局锁
- 分布式锁必须设置超时时间（防止死锁），建议默认 30 秒
- 幂等方案优先于加锁：唯一约束、去重表、Token 机制比分布式锁更可靠
- 超卖/超扣场景必须使用数据库原子操作（UPDATE SET stock = stock - 1 WHERE stock >= 1），禁止先查后改
- 乐观锁冲突必须有用户可见提示（"数据已被修改，请刷新重试"），禁止静默失败
- 批量并发操作必须限制并发度（信号量/线程池），禁止无限制并发
- ThreadLocal 必须在请求结束时 remove()，否则线程池复用导致数据串线
- 锁的获取和释放必须在同一个 try-finally 块中，防止异常导致死锁
- 分布式锁必须设置过期时间（如 30s），防止持有者崩溃导致永久死锁
- 原子操作优先使用 CAS（AtomicInteger/LongAdder），无竞争场景性能优于锁
- 线程池必须通过 ThreadPoolExecutor 构造函数创建，禁止使用 Executors（避免 OOM）

## 验收项
- [AC-01] 共享可变状态操作有显式并发控制策略
- [AC-02] 分布式锁有超时设置
- [AC-03] 超卖场景使用原子操作而非先查后改
- [AC-04] 乐观锁冲突有用户提示
- [AC-05] 批量并发操作有并发度限制
- [AC-06] ThreadLocal 请求结束清理
- [AC-07] 锁释放 try-finally 保护
- [AC-08] 分布式锁有超时时间
- [AC-09] 线程池显式创建
