首页/数据/SQL 速查/事务隔离级别与设置方法
变更与事务52 条

事务隔离级别与设置方法

四档隔离级别控制并发读写行为:MySQL 默认 REPEATABLE READ,PostgreSQL 默认 READ COMMITTED;改级别可按会话或按事务。

SQL 速查数据更新于 2026-10-13

事务隔离级别是什么

隔离级别控制并发事务之间能看到什么,共四档: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 必须配重试逻辑,并限制重试次数
  • 把级别的设置写在连接初始化脚本里,避免依赖默认值

易错点

  • 把 MySQL 的 REPEATABLE READ 经验直接套到 PG:两库快照时机与幻读处理不同,并发逻辑要重新验证
  • SERIALIZABLE 下应用缺少重试逻辑,并发高峰直接抛错
  • 在会话级临时改了隔离级别而忘记恢复,影响连接池里后续复用的请求
  • 以为提高级别就能解决所有并发问题,忽略锁等待与死锁带来的新问题
  • 依赖数据库默认值而不显式声明,换版本或换实例后行为悄悄变化

数据来源与参考

  • MySQL 8.0 Reference Manual · Transaction Isolation Levels
  • PostgreSQL Documentation · Transaction Isolation
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌