事务隔离级别是什么
隔离级别控制并发事务之间能看到什么,共四档:READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ、SERIALIZABLE。MySQL 的 InnoDB 默认 REPEATABLE READ,PostgreSQL 默认 READ COMMITTED,这个差异是跨库迁移时最容易忽略的点。级别可以按会话设置,也可以只作用于下一个事务。级别越高一致性越强、并发冲突越多,SERIALIZABLE 下应用必须实现重试逻辑。把一库的并发经验直接套到另一库并不安全,两库的快照时机与幻读处理机制不同。
基本信息
| 四档级别 | READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ、SERIALIZABLE |
|---|---|
| MySQL 默认 | REPEATABLE READ(InnoDB) |
| PostgreSQL 默认 | READ COMMITTED |
| 会话级设置 | SET SESSION TRANSACTION ISOLATION LEVEL 级别 |
| 单事务设置 | SET TRANSACTION ISOLATION LEVEL 级别,或 BEGIN ISOLATION LEVEL 级别 |
| PostgreSQL 特例 | READ UNCOMMITTED 实际按 READ COMMITTED 处理 |
典型使用场景
- 统计报表:用 REPEATABLE READ 让同一事务内多次读取结果一致
- 高并发写入:用 READ COMMITTED 减少锁等待与冲突
- 批量任务:降低级别换取吞吐
- 对账与结算:提高级别或加锁读保证口径一致
- 排查并发问题:临时切换级别复现现象
- 迁移验证:核对两库在默认级别下的行为差异
MySQL 设置方式
MySQL 设置方式
SELECT @@transaction_isolation; # 查看当前级别
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; # 本会话生效
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; # 仅下一个事务
-- 事务内确认
START TRANSACTION;
SELECT @@transaction_isolation;
COMMIT;PostgreSQL 设置方式
PostgreSQL 设置方式
SHOW default_transaction_isolation; # 查看默认级别
-- 只影响下一个事务
BEGIN ISOLATION LEVEL REPEATABLE READ;
-- 或事务内设置
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
-- 解决序列化冲突的常见做法:捕获错误后重试
-- PostgreSQL 报错码 40001,应用层需要有重试逻辑四档级别概览
| 级别 | 可能出现的问题 | 说明 |
|---|---|---|
| READ UNCOMMITTED | 脏读 | PostgreSQL 实际按 READ COMMITTED 处理 |
| READ COMMITTED | 不可重复读 | PostgreSQL 默认;每次语句取新快照 |
| REPEATABLE READ | 幻读(视实现) | MySQL 默认,InnoDB 用一致性读 |
| SERIALIZABLE | 串行化失败需重试 | PostgreSQL 用 SSI 检测冲突 |
MySQL 的 REPEATABLE READ 在事务内多次读取结果一致,PostgreSQL 的 READ COMMITTED 每条语句取新快照,同一段代码在两库的表现可能不同。
SERIALIZABLE 下应用必须实现重试:PostgreSQL 会返回序列化失败错误,MySQL 可能出现死锁,没有重试逻辑在并发高峰会直接报错。
级别不是越高越好:并发冲突增多会带来大量重试与锁等待,选择依据是业务对一致性的真实要求。
使用要点
- 先明确业务能接受哪种异常:脏读、不可重复读还是幻读
- 默认级别差异写进迁移文档,避免照搬经验
- 需要跨语句一致读时用 REPEATABLE READ 或显式加锁读
- 高并发写入场景优先 READ COMMITTED 降低冲突
- SERIALIZABLE 必须配重试逻辑,并限制重试次数
- 把级别的设置写在连接初始化脚本里,避免依赖默认值