PostgreSQL 支持哪些事务隔离级别?
PostgreSQL 语法上完全支持 SQL 标准中定义的 4 种事务隔离级别,但在其底层的具体实现上(基于 MVCC 多版本并发控制),具有自己的一些特点。
PostgreSQL 的默认隔离级别是 Read Committed(读已提交)。
以下是这 4 种隔离级别在 PostgreSQL 中的具体表现:
1. 读未提交 (Read Uncommitted)
- SQL 标准: 允许读取未提交的数据(脏读)。
- PostgreSQL 实现: 虽然你可以在代码中设置这个级别,但在 PostgreSQL 中,它的实际表现和 Read Committed(读已提交)完全一样。因为 PostgreSQL 底层使用的是 MVCC(多版本并发控制),天生不支持且绝对不会发生“脏读”。
2. 读已提交 (Read Committed) —— [默认级别]
- 特点: 一个事务只能看到在它当前查询(Query)开始之前已经提交的数据。
- 存在的问题:
- 允许不可重复读 (Non-repeatable Read):在同一个事务中,如果执行两次相同的
SELECT查询,期间如果有另一个事务修改并提交了这些数据,两次查询的结果会不一样。 - 允许幻读 (Phantom Read):在同一个事务中,同样的查询条件,由于其他事务插入或删除了满足条件的数据并提交,后一次查询可能会查出“多出来”或“少掉”的行。
- 允许不可重复读 (Non-repeatable Read):在同一个事务中,如果执行两次相同的
3. 可重复读 (Repeatable Read)
- 特点: 一个事务只能看到在当前事务(Transaction)开始之前已经提交的数据。在整个事务期间,它看到的是数据库的一个一致性快照。
- PostgreSQL 的特殊之处: 在 SQL 标准中,可重复读级别是允许发生“幻读”的。但是,在 PostgreSQL 中,该级别下不仅防止了脏读和不可重复读,同时也防止了幻读。
- 注意事项: 当两个并发事务尝试修改同一行数据时,只有一个会成功。后一个尝试修改的事务会报错 (
ERROR: could not serialize access due to concurrent update),此时必须由应用程序捕获错误并重试整个事务。
4. 可串行化 (Serializable)
- 特点: 最严格的隔离级别。它保证并发执行的事务结果,必定与某种依次串行执行(一个接一个执行)的结果完全相同。
- 实现原理: PostgreSQL 使用了 可串行化快照隔离 (SSI)。它不仅具有
Repeatable Read的一切特性,还会监控事务之间的读写依赖关系。如果发现可能产生不一致的情况(即序列化异常),它会主动中止其中一个事务并报错 (ERROR: could not serialize access due to read/write dependencies among transactions)。 - 注意事项: 使用此级别会增加系统开销,并且应用程序必须具备完善的事务重试机制。
现象总结表 (针对 PostgreSQL 实际运行情况)
| 隔离级别 | 脏读 (Dirty Read) | 不可重复读 (Non-repeatable Read) | 幻读 (Phantom Read) | 序列化异常 (Serialization Anomaly) |
|---|---|---|---|---|
| Read Uncommitted | ❌ (被PG阻止) | ✅ 允许 | ✅ 允许 | ✅ 允许 |
| Read Committed (默认) | ❌ 防止 | ✅ 允许 | ✅ 允许 | ✅ 允许 |
| Repeatable Read | ❌ 防止 | ❌ 防止 | ❌ (被PG阻止) | ✅ 允许 |
| Serializable | ❌ 防止 | ❌ 防止 | ❌ 防止 | ❌ 防止 |
注:表中的“被PG阻止”表示虽然 SQL 标准允许该现象,但 PostgreSQL 的底层机制(MVCC)天然消除了这种现象。
如何在 PostgreSQL 中设置隔离级别?
1. 在开启事务时指定(仅对当前事务有效):
sql
BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
-- 或者
START TRANSACTION ISOLATION LEVEL SERIALIZABLE;
2. 在事务内部修改(必须在执行任何查询或修改前):
sql
BEGIN;
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
3. 设置当前会话(Session)的默认级别:
sql
SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL READ COMMITTED;
右滑查看面试常问