↑↓ 选择 ↵ 打开 ⌫ 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
测试与开发版本: 19 / devel
不受支持的版本: 13 / 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2
历史版本PostgreSQL 7.2 已于 2007 年 2 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本。

3.4. 事务 #

事务是所有数据库系统中的一个基本概念。事务的要点在于,它把多个步骤打包成一个单一的、要么全部成功要么全部失败的操作。步骤之间的中间状态对其他并发事务不可见;如果发生某种故障使事务无法完成,那么其中任何一步都不会对数据库产生影响。

例如,考虑一个银行数据库,其中保存着各个客户账户的余额,以及各营业网点的总存款余额。假设我们要记录一笔从Alice的账户向Bob的账户支付100.00美元的款项。大幅简化后,相应的 SQL 命令可能是:

UPDATE accounts SET balance = balance - 100.00
    WHERE name = 'Alice';
UPDATE branches SET balance = balance - 100.00
    WHERE name = (SELECT branch_name FROM accounts WHERE name = 'Alice');
UPDATE accounts SET balance = balance + 100.00
    WHERE name = 'Bob';
UPDATE branches SET balance = balance + 100.00
    WHERE name = (SELECT branch_name FROM accounts WHERE name = 'Bob');

这些命令的细节在这里并不重要;重要的是,为了完成这个相当简单的操作,涉及了若干次彼此独立的更新。银行管理人员会希望确信这些更新要么全部发生,要么一个也不发生。显然,不能因为系统故障导致Bob收到了100.00美元,而Alice那边却没有被扣款。反过来,如果Alice被扣了款而Bob没有入账,她也不会满意。我们需要保证:如果操作进行到一半出了问题,到目前为止已执行的步骤都不会生效。把这些更新归为一个事务,就能提供这种保证。事务被称为原子的:从其他事务的角度看,它要么完整发生,要么根本不发生。

我们还希望保证,一旦事务完成并得到数据库系统确认,它确实已经被永久记录下来,即便紧接着发生崩溃也不会丢失。例如,如果我们正在记录Bob的一次现金提款,我们当然不希望他刚走出银行大门,对他账户的扣款就在崩溃后消失。事务型数据库保证,在把事务报告为完成之前,会先将该事务所做的全部更新记入永久存储(即磁盘)。

事务型数据库的另一个重要性质与原子更新的概念密切相关:当多个事务并发运行时,每个事务都不应该看到其他事务尚未完成的更改。例如,如果某个事务正在统计所有营业网点的余额,就不能让它只算进Alice所在网点的扣款,却没有算进Bob所在网点的入账,反过来也不行。因此,事务不仅在对数据库的持久影响上必须是全有或全无的,在其发生过程中的可见性上也必须如此。一个未结束事务到目前为止所做的更新,对其他事务不可见;等到该事务完成时,所有更新会同时变得可见。

在PostgreSQL中,可以通过将事务中的 SQL 命令置于BEGIN和COMMIT命令之间来建立一个事务。因此,我们的银行事务实际上会是这样:

BEGIN;
UPDATE accounts SET balance = balance - 100.00
    WHERE name = 'Alice';
-- etc etc
COMMIT;

如果事务执行到一半时,我们决定不想提交了(例如刚刚发现Alice的余额变成了负数),就可以发出ROLLBACK而不是COMMIT,这样到目前为止的全部更新都会被取消。

PostgreSQL实际上把每条 SQL 语句都视为在一个事务中执行。如果你没有显式发出BEGIN,那么每条独立语句外围都会隐式包上一对BEGIN和(若成功)COMMIT。由BEGIN和COMMIT包围起来的一组语句,有时称为事务块。

注意

某些客户端库会自动发出BEGIN和COMMIT命令,因此你可能在没有主动要求的情况下,也得到了事务块的效果。请查阅你所使用接口的文档。

提交更正

译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。