隔离性(Isolation)是数据库事务的ACID四大特性之一,指多个并发事务在执行过程中应相互隔离
隔离性(Isolation)是数据库事务的ACID四大特性之一,指多个并发事务在执行过程中应相互隔离、互不干扰,即一个事务的执行不应被其他并发事务所影响,从而保证数据的一致性和正确性。隔离性通过事务隔离级别(如读未提交、读已提交、可重复读、串行化)来实现,不同级别在性能与一致性之间进行权衡:级别越高,隔离越强,但并发性能越低;级别越低,并发性越好,但可能出现脏读、不可重复读或幻读等问题。
常见的隔离级别及其典型问题:
- 读未提交(Read Uncommitted):最低级别,允许读取未提交的数据 → 可能发生脏读;
- 读已提交(Read Committed):只能读取已提交的数据 → 避免脏读,但可能不可重复读;
- 可重复读(Repeatable Read):同一事务内多次读取结果一致 → 避免脏读和不可重复读,但可能幻读(MySQL InnoDB通过间隙锁解决部分幻读);
- 串行化(Serializable):最高级别,强制事务串行执行 → 完全避免并发异常,但严重牺牲并发性能。
实现机制通常依赖于锁(如行锁、表锁、间隙锁)或无锁技术(如MVCC,多版本并发控制),例如 PostgreSQL 和 MySQL(InnoDB)均采用 MVCC 实现高并发下的快照读,兼顾隔离性与性能。
MySQL(InnoDB引擎)默认隔离级别为可重复读(Repeatable Read),而PostgreSQL默认为读已提交(Read Committed),这一差异源于二者在设计目标、历史演进、并发控制机制及对“一致性快照”语义的不同权衡:
✅MySQL选择RR的动因:
- 解决主从复制一致性问题(历史原因):早期MySQL基于语句级复制(Statement-Based Replication, SBR),若使用RC级别,在同一事务中多次查询可能因并发更新导致主库与从库执行结果不一致(例如
UPDATE ... WHERE SELECT类操作)。RR通过MVCC提供事务内一致性快照(consistent snapshot),确保事务内多次读取结果稳定,使SBR更可靠。虽然后续支持ROW模式复制,但默认级别保持向后兼容。 - InnoDB的强MVCC实现:InnoDB在RR级别下为每个事务分配一个全局唯一的事务ID(trx_id),并基于聚簇索引记录的
DB_TRX_ID和DB_ROLL_PTR构建版本链,配合间隙锁(Gap Lock)/临键锁(Next-Key Lock)有效抑制幻读(尤其在范围查询+DML场景),使得RR在实践中比标准SQL定义更严格(SQL标准中RR不保证无幻读,但InnoDB做到了部分规避)。 - 用户预期与简化开发:开发者常期望“事务内读一致性”,RR天然满足该直觉,降低应用层手动加锁或重试逻辑的复杂度。
✅PostgreSQL选择RC的动因:
- 遵循SQL标准且强调简单性与高性能:SQL标准将RC定义为“最低保证无脏读”的合理默认,PostgreSQL严格遵循标准,并认为“可重复读”属于需显式声明的高级需求。
- MVCC实现机制不同:PostgreSQL的MVCC基于行版本(tuple visibility)和事务快照(snapshot),每个查询开始时获取一个当前活跃事务ID快照,只看到该快照前已提交的数据。因此:
- RC级别下,每次SELECT都获取新快照→ 同一事务内不同查询可能看到不同数据(不可重复读);
- RR级别下,整个事务复用首次查询的快照→ 实现真正可重复读(且完全避免幻读,因其快照包含所有已提交事务状态,不含未提交变更)。
由于PG的RR开销与RC接近(快照复用成本低),它仍允许用户按需升级,但默认倾向更轻量、更符合直觉的RC。
- 无锁设计哲学:PG避免使用间隙锁等阻塞机制,依赖纯MVCC + 行级版本判断,RC已能很好平衡并发与正确性,过度隔离反而增加锁竞争和死锁风险。
📌 关键区别总结:
| 维度 | MySQL (InnoDB) | PostgreSQL |
|---|---|---|
| 默认隔离级别 | REPEATABLE READ | READ COMMITTED |
| 快照粒度 | 事务启动时创建(第一次SELECT时)→ 整个事务共享 | 每条SQL语句开始时创建 → 同事务内可变 |
| 幻读处理 | RR下通过间隙锁/临键锁抑制(非纯MVCC) | RR下靠快照一致性彻底避免(纯MVCC) |
| 设计哲学 | “事务内一致性优先”,兼顾复制可靠性 | “标准兼容 + 高并发优先”,默认最小必要隔离 |
因此,这不是优劣之分,而是架构取舍:MySQL以“写一致性”和“复制鲁棒性”为导向,PostgreSQL以“标准合规”和“读扩展性”为导向。
