全书目录

第八篇:PostgreSQL 完全指南 —— 时间档案馆宇宙

第六章:事务 —— 一次归档,要么全部成功,要么全部不算

1 分钟 401 字 第 170 / 962 个阅读单元

事务的本质不是语法,而是:

把多个步骤打包成一个不可分割的操作。

比如签发通行证,不应该出现“证件建好了,但日志没写”这种半完成状态。

sql
BEGIN;

INSERT INTO permits (
  citizen_id, permit_type, valid_from, valid_to, status, meta
) VALUES (
  1, 'cross_district', CURRENT_DATE, CURRENT_DATE + INTERVAL '30 days',
  'active', '{"channel":"counter"}'
);

INSERT INTO permit_events (
  permit_id, event_type, payload
) VALUES (
  currval(pg_get_serial_sequence('permits', 'permit_id')),
  'issued',
  '{"operator":"clerk-17"}'
);

COMMIT;

中间任一步失败,都可以:

sql
ROLLBACK;

这就是“要么整批入馆,要么整批作废”。

事务隔离级别可以先记这张表:

隔离级别 你可以怎么理解
READ COMMITTED 默认级别。每条语句看自己开始时的快照
REPEATABLE READ 整个事务看同一批快照
SERIALIZABLE 像所有事务按串行顺序一个个执行

默认是:

sql
SHOW default_transaction_isolation;

PostgreSQL 官方文档明确说明:

  • READ COMMITTED 是默认级别
  • READ UNCOMMITTED 在 PostgreSQL 里会按 READ COMMITTED 处理
  • SERIALIZABLE 最严格,但应用必须准备好重试事务

例如:

sql
BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;

-- 一组依赖全局一致性的读写逻辑

COMMIT;

如果报:

text
ERROR: could not serialize access ...

不是 PostgreSQL 坏了,而是它在保护你。 正确做法是:回滚并重试整个事务。