选 sql 隔离级别需平衡一致性与性能:读已提交适用于高 并发 只读场景,可重复读适合 金融 强一致事务,串行化仅用于极少数严格串行需求,读未提交几乎不用。

选 SQL 隔离级别,核心是平衡数据一致性与系统性能。不是越高的隔离级别越好,而是看业务能否容忍某些并发现象,比如脏读、不可重复读或幻读。
高并发查询类场景:读已提交(Read Committed)最常用
电商商品列表页、新闻资讯 流、用户资料查看等,通常只读不改,且能接受“刚提交的数据下一次查询才看到”。
Read Committed 能避免脏读,又不会像可重复读那样加过多锁或启用 MVCC 快照开销,吞吐量高、延迟低。
大多数 数据库(如 postgresql、SQL Server、oracle)默认就是它;mysql InnoDB 默认是可重复读,但多数只读场景其实降级到读已提交更合适。
- 适用操作:select 多、UPDATE/INSERT 少;无强事务连续读需求
- 注意点:同一事务中两次 SELECT 可能结果不同(不可重复读),但业务上往往无感
- 优化提示:配合索引和只查必要字段,比升级隔离级别更能提升性能
金融/ 订单类强一致性场景:可重复读(Repeatable Read)更稳妥
下单扣库存、支付状态核对、账户余额校验等,要求同一事务内多次读取结果一致。例如:先查余额够不够,再扣款——中间不能被其他事务改掉余额。
- InnoDB 的可重复读通过 MVCC 实现,不阻塞读,兼顾一致性与并发性
- 注意幻读问题:范围查询(如 SELECT * FROM orders WHERE status=’pending’)仍可能新增记录;需用 SELECT … for UPDATE 或加唯一约束 + 重试逻辑规避
- 避免长事务:长时间持有快照会拖慢 purge 线程,影响整体性能
极少数严格串行场景:串行化(Serializable)慎用
银行日终轧账、跨库资金对账、审计类批处理——要求绝对无并发干扰,宁可牺牲性能也要 100% 正确。
- 本质是把并发事务变成排队执行,写操作常触发锁等待甚至超时
- MySQL 中会将所有 SELECT 隐式转为 SELECT … LOCK IN SHARE MODE,容易引发死锁
- 建议:优先用应用层加 分布式 锁 + 较低隔离级别组合替代;必须用时限定在最小事务粒度和最短时间窗口
特殊需求:读未提交(Read Uncommitted)几乎不用
理论上允许脏读,现实中极少主动选用。个别离线分析场景(如实时日志统计容错率高)可能临时设置,但风险大、可维护性差,不推荐作为常规方案。
- 无法保证任何一致性,连“已提交”都不保障
- 多数数据库不支持(如 PostgreSQL 直接禁用该级别)
- 真要极致性能,不如考虑物化视图、缓存或 异步 计算