0Pricing
SQL Academy · 课时

隔离级别:READ COMMITTED、REPEATABLE READ、SERIALIZABLE

比较 SQL 标准中的隔离级别及 PostgreSQL 的实现,并为您的工作负载选择合适的级别

隔离级别:READ COMMITTED、REPEATABLE READ、SERIALIZABLE 是 CoddyKit 上的免费 SQL Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 SQL Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 SQL Academy 课程共包含 4 节课。

四个标准级别

SQL 标准定义了四个隔离级别:

  • READ UNCOMMITTED
  • READ COMMITTED
  • REPEATABLE READ
  • SERIALIZABLE

PostgreSQL 实现了其中三个(READ UNCOMMITTED 的行为与 READ COMMITTED 相同)。

READ COMMITTED(PostgreSQL 默认级别)

每条语句都能看到在该语句开始前已 COMMIT 的数据。在同一个事务中,您可能会看到不同的数据快照。

-- Inside one transaction:
SELECT balance FROM accounts WHERE id = 1;  -- 100
-- meanwhile another tx commits balance=200
SELECT balance FROM accounts WHERE id = 1;  -- 200  (non-repeatable read)

REPEATABLE READ(快照隔离)

读取事务开始时获取的快照。重复读取同一行时,始终返回相同的值。PostgreSQL 的 REPEATABLE READ 还会阻止幻读。

BEGIN ISOLATION LEVEL REPEATABLE READ;
SELECT balance FROM accounts WHERE id = 1;  -- 100
-- another tx commits balance=200
SELECT balance FROM accounts WHERE id = 1;  -- still 100
COMMIT;

SERIALIZABLE

最强的隔离级别:效果如同事务按顺序一个接一个地运行。PostgreSQL 使用可串行化快照隔离(SSI)——检测并发依赖,并中止相互冲突的事务:

BEGIN ISOLATION LEVEL SERIALIZABLE;
...
COMMIT;
-- ERROR: could not serialize access due to read/write dependencies

设置隔离级别

可以针对每个事务、每个会话或全局设置:

-- Per transaction:
BEGIN ISOLATION LEVEL SERIALIZABLE;

-- Per session:
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;

-- Default for new transactions in this session:
SET default_transaction_isolation = 'repeatable read';

-- Global default in postgresql.conf:
-- default_transaction_isolation = 'read committed'

各级别允许的异常

级别脏读不可重复读幻读
READ UNCOMMITTED可能可能可能
READ COMMITTED否可能可能
REPEATABLE READ否否否(在 PG 中)
SERIALIZABLE否否否

性能权衡

  • READ COMMITTED — 开销最低,默认级别
  • REPEATABLE READ — 使用相同快照,读取一致;除非发生写冲突,否则不会影响性能
  • SERIALIZABLE — 需要额外记录,可能中止事务;应用需要重试逻辑

可串行化重试模式

SERIALIZABLE 可能因错误代码 40001 而中止。请在循环中重试:

for (let i = 0; i < 3; i++) {
  try {
    await client.query('BEGIN ISOLATION LEVEL SERIALIZABLE');
    // ... work ...
    await client.query('COMMIT');
    break;
  } catch (e) {
    if (e.code === '40001') continue;
    throw e;
  }
}

读取一致的快照

对于需要一致数据的长时间运行分析查询,REPEATABLE READ 是较为合适的平衡选择。

写冲突行为

如果两个事务修改同一行:

  • READ COMMITTED — 第二个事务等待,然后重新读取新行并重试
  • REPEATABLE READ — 第二个事务因“无法串行化”而中止,应用必须重试

选择合适的级别

经验法则:

  • OLTP — READ COMMITTED(默认)
  • 需要一致性的报告 — REPEATABLE READ
  • 资金或库存 — SERIALIZABLE + 重试,或使用显式锁(FOR UPDATE)

有时显式锁优于隔离性

对于单个热点行,在 READ COMMITTED 下使用 SELECT ... FOR UPDATE 通常比 SERIALIZABLE 更简单。

回顾

隔离级别需要在安全性与并发性之间进行权衡。

  • READ COMMITTED 是默认级别
  • 使用 REPEATABLE READ 获得一致性读取
  • SERIALIZABLE 提供“如同串行执行”的效果,但需要重试逻辑

快速检查

PostgreSQL 的默认隔离级别是哪一个?

常见问题解答

「隔离级别:READ COMMITTED、REPEATABLE READ、SERIALIZABLE」课时是免费的吗?

是的 — 「隔离级别:READ COMMITTED、REPEATABLE READ、SERIALIZABLE」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 SQL Academy 课程的其余内容,请升级到 CoddyKit PRO。 SQL Academy 课程共包含 4 节课。

「隔离级别:READ COMMITTED、REPEATABLE READ、SERIALIZABLE」这节课中我会学到什么?

比较 SQL 标准中的隔离级别及 PostgreSQL 的实现,并为您的工作负载选择合适的级别 你通过在浏览器中直接运行的动手代码来练习 SQL Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 SQL Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 SQL Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。

「隔离级别:READ COMMITTED、REPEATABLE READ、SERIALIZABLE」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 SQL Academy 课中编写并运行代码吗?

能。每节 SQL Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. ACID 属性与异常
  2. 隔离级别:READ COMMITTED、REPEATABLE READ、SERIALIZABLE
  3. 死锁:检测与避免
  4. 乐观锁与悲观锁
← 返回 SQL Academy