可串行化是什么
可串行化(Serializability)是事务隔离的最高级别:并发事务的最终执行结果,等价于这些事务按某个串行顺序依次执行。它保证涉及多个对象的事务不会出现写偏斜、幻读等异常,代价是冲突时阻塞或回滚重试,吞吐随之下降。需要注意的是它与线性一致侧重点不同:可串行化约束的是事务之间的等价关系,线性一致约束的是单对象上的实时先后顺序,两者不是同一件事。
基本信息
| 保证范围 | 多对象事务的执行结果等价于某种串行顺序 |
|---|---|
| 实现方式 | 两阶段锁、乐观并发控制、串行图检测 |
| 主要代价 | 冲突时阻塞或重试,吞吐与尾延迟受影响 |
| 与线性一致的区别 | 前者约束事务等价性,后者约束单对象的实时顺序 |
| 工程现实 | 多数数据库的「可重复读」并非快照隔离的完全等价物,需按具体实现确认 |
典型使用场景
- 账务扣减:余额计算与流水写入必须保持原子语义,不能出现中间态被读到
- 库存扣减:并发下单时避免超卖,涉及多行更新的约束检查
- 唯一性约束校验:先查后插的场景在低隔离级别下可能被并发插入破坏
- 多表一致性维护:主表与明细表状态必须同步推进的业务操作
- 对账与冲正:批量修正数据时要求事务之间互不干扰
- 序列号分配:号码段与业务单据必须一一对应
隔离级别与典型异常
| 级别 | 可能异常 | 适用场景 |
|---|---|---|
| 读已提交 | 不可重复读、写偏斜 | 一般业务查询与展示 |
| 可重复读 | 写偏斜、幻读(视具体实现而定) | 多数交易类业务,需按数据库实现核对 |
| 可串行化 | 理论上无异常,代价是冲突重试 | 账务、库存等强约束场景 |
| 快照隔离 | 写偏斜仍可能发生 | 读多写少且可接受冲突较轻的场景 |
落地要点
落地要点
# 1 按业务风险选级别:只有涉及金额、库存与唯一性约束的操作才需要最高级别
# 2 冲突必重试:可串行化下序列化冲突是正常现象,业务层需有重试上限与退避
# 3 事务要短:事务内不要做远程调用、发消息或等待用户输入,否则锁持有时间被拉长
# 4 加锁顺序统一:多个事务访问同一批记录时使用固定顺序,降低死锁概率
# 5 观测:统计冲突率、重试次数与事务平均耗时,超阈值需调整设计
# 6 校验:用并发测试脚本验证约束在目标隔离级别下确实成立多数业务只需要可串行化的一个子集(例如快照隔离加显式的唯一约束或版本校验),默认把全部事务提到最高级别通常得不偿失。
出现序列化冲突后没有重试策略时,业务会随机失败:调用方看到偶发报错却难以复现,务必把重试与退避写进接入规范。