首页/开发/系统分析与架构设计速查/并发异常与处理手段

并发异常与处理手段

常见并发异常包括丢失更新、写偏斜、幻读与脏写;处理手段有乐观锁(版本号)、悲观锁(行锁或 SELECT FOR UPDATE)与提高隔离级别。

并发异常是什么

并发异常指多个事务交叉执行造成的数据不一致,常见有丢失更新、写偏斜、幻读与脏写。它们的共性是:两个事务读到同一份数据,各自基于读到的事实做出判断,而写入时对方的修改已经生效,先前的判断不再成立。

对策怎么选

乐观锁用版本号在提交时校验,冲突则重试,适合冲突率低的场景;悲观锁用行锁或查询加锁在读取阶段就排他,适合冲突率高的场景,代价是持锁期间阻塞其他人;把隔离级别提到可串行化能让数据库替你检测冲突,但要处理序列化失败后的重试。

异常与对策

异常现象常用对策
丢失更新两次读改写互相覆盖版本号乐观锁、行锁
写偏斜两个事务各改一半破坏约束可串行化隔离、显式锁
幻读范围查询结果集发生变化间隙锁、可串行化
脏写覆盖未提交的写入数据库写锁,多数库默认防止

基本信息

乐观锁版本号或条件更新,提交时校验,冲突重试
悲观锁行锁或查询加锁,读取阶段即排他
隔离级别提升到可串行化,由数据库检测冲突
必备配套重试必须幂等,且限定次数与退避策略

典型使用场景

  • 库存扣减:用版本号或条件更新避免超卖
  • 账户余额:并发入账需要读改写原子完成
  • 范围校验:如会议室预定不可重叠,需要可串行化或间隙锁
  • 幂等重试:任何重试路径都必须可以安全重复执行
  • 批处理与在线事务并发:控制批量更新的锁范围与执行时段
乐观锁失败要配合重试与幂等,否则用户会看到随机报错。重试次数与退避策略同样是设计的一部分,不受限的重试会把冲突转化为重试风暴。

易错点

  • 用先查再改的方式实现扣减,既未加锁也未用版本号,高并发下必然超卖
  • 乐观锁重试次数无上限,冲突时形成重试风暴,把数据库压力进一步放大
  • 长事务里持有行锁并等待外部调用,锁等待时间被网络延迟无限拉长
  • 只在高并发场景验证,忽略了批处理任务与在线事务同时运行的冲突

数据来源与参考

  • 《数据密集型应用系统设计》(Kleppmann)第 7 章
  • PostgreSQL 文档:Transaction Isolation
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌