并发异常是什么
并发异常指多个事务交叉执行造成的数据不一致,常见有丢失更新、写偏斜、幻读与脏写。它们的共性是:两个事务读到同一份数据,各自基于读到的事实做出判断,而写入时对方的修改已经生效,先前的判断不再成立。
对策怎么选
乐观锁用版本号在提交时校验,冲突则重试,适合冲突率低的场景;悲观锁用行锁或查询加锁在读取阶段就排他,适合冲突率高的场景,代价是持锁期间阻塞其他人;把隔离级别提到可串行化能让数据库替你检测冲突,但要处理序列化失败后的重试。
异常与对策
| 异常 | 现象 | 常用对策 |
|---|---|---|
| 丢失更新 | 两次读改写互相覆盖 | 版本号乐观锁、行锁 |
| 写偏斜 | 两个事务各改一半破坏约束 | 可串行化隔离、显式锁 |
| 幻读 | 范围查询结果集发生变化 | 间隙锁、可串行化 |
| 脏写 | 覆盖未提交的写入 | 数据库写锁,多数库默认防止 |
基本信息
| 乐观锁 | 版本号或条件更新,提交时校验,冲突重试 |
|---|---|
| 悲观锁 | 行锁或查询加锁,读取阶段即排他 |
| 隔离级别 | 提升到可串行化,由数据库检测冲突 |
| 必备配套 | 重试必须幂等,且限定次数与退避策略 |
典型使用场景
- 库存扣减:用版本号或条件更新避免超卖
- 账户余额:并发入账需要读改写原子完成
- 范围校验:如会议室预定不可重叠,需要可串行化或间隙锁
- 幂等重试:任何重试路径都必须可以安全重复执行
- 批处理与在线事务并发:控制批量更新的锁范围与执行时段
乐观锁失败要配合重试与幂等,否则用户会看到随机报错。重试次数与退避策略同样是设计的一部分,不受限的重试会把冲突转化为重试风暴。