标准答案
- Read Committed 通常为每条语句建立快照,所以同一事务中的两条 SELECT 可能看到不同时间点已经提交的数据。这适合多数短事务,但不保证整个事务读到同一视图。
- Repeatable Read 通常使用事务级快照,同一事务重复读取能保持一致视图;如果并发写入与该快照发生冲突,事务可能在提交或执行过程中失败。
- Serializable 在更强约束下检测可能破坏串行结果的并发关系。应用必须把整个事务作为可重试单元,重新读取、判断并提交,不能只重跑最后一条 SQL。
- 隔离级别不是越高越好。越强的隔离通常意味着更多冲突、等待或重试,应该围绕库存不超卖、余额不为负、审批不覆盖等具体不变量选择。
- 排查可见性问题时要确认事务是否真的跨越多条语句、连接是否被连接池错误复用,以及查询使用的是普通快照读还是锁定/当前读。
题目解析
隔离级别描述数据库事务内部的可见性和并发冲突边界,不会自动覆盖消息、缓存、HTTP 调用或其他数据库的状态。因此跨系统流程仍需要幂等、补偿和状态机。
例如扣库存时,单纯把事务改成 Repeatable Read 并不能替代“库存大于零的条件更新”或合适的锁;最终要让业务不变量落在数据库能裁决的条件上。
面试中应说明失败后的处理:可重试的事务要限制次数并使用退避,不可安全重试的外部副作用要放在事务外或先记录可恢复的业务意图。
常见误区
- 误区:把 Repeatable Read 理解为事务永远不会回滚。改正:它提供更稳定的读取视图,但并发写冲突、死锁或序列化判断仍可能让事务失败。
- 误区:序列化失败后只重试报错的那条 SQL。改正:前面的读取和业务判断也可能已经过期,通常需要重新执行整个事务。
- 误区:认为提高隔离级别就能解决分布式一致性。改正:数据库隔离只覆盖当前数据库事务,跨服务结果仍需独立设计。