跳至内容

PostgreSQL/事务

来自维基教科书,开放的书本,开放的世界


所有更改数据的操作,如 INSERTUPDATEDELETE,必须在称为 TRANSACTION 的周围结构内运行。事务使用 SQL 命令 BEGIN 创建,并使用 COMMITROLLBACK 完成。在事务的生命周期中,对数据库的更改仅初步写入。最后,COMMIT 正式完成事务并提交所有预期的数据更改,或者 ROLLBACK 终止事务并恢复所有这些初步更改。

除了显式使用 SQL 关键字来管理事务之外,PostgreSQL 的一些客户端库会在数据更改操作未在显式创建的事务中运行的情况下隐式创建一个新事务。在这种情况下,操作会在执行后立即自动提交。

BEGIN; -- establish a new transaction
UPDATE accounts SET balance = balance - 100.00 WHERE name = 'Alice';
UPDATE accounts SET balance = balance + 100.00 WHERE name = 'Bob';
COMMIT; -- finish the transaction

-- this UPDATE runs as the only command of an implicitly created transaction ...
UPDATE accounts SET balance = balance - 100.00 WHERE name = 'Alice';

-- ... and this one runs in another transaction
UPDATE accounts SET balance = balance + 100.00 WHERE name = 'Bob';
提示:在过程或函数中工作时,有一个 DECLARE ... BEGIN ... END; 结构来定义 '块'。在这种情况下,BEGIN 的含义(BEGIN 后面没有分号!)与这里解释的不同。您可以在事务上下文中使用关键字 START TRANSACTION; 作为 BEGIN; 的替代方案来避免歧义。除此之外,START TRANSACTION; 符合 SQL 标准。

事务为应用程序提供了极大的便利。特别是对于必须将许多语句作为一个一致的单元执行的业务逻辑(例如上述从一个银行帐户到另一个银行帐户的转账),无需在事务执行过程中发生错误后采取单独的行动。在许多情况下,只需重新启动事务或以统一的方式处理错误即可。

PostgreSQL 中的事务保证了 ACID 原则的所有要求都得到满足,请参阅下一章

子事务

[编辑 | 编辑源代码]

在事务中,关键字 SAVEPOINT 定义并表示一个位置,事务可以回滚到该位置。

-- The transaction will insert the values 1 and 3, but not 2.
BEGIN;
INSERT INTO my_table VALUES (1);
SAVEPOINT my_savepoint;
INSERT INTO my_table VALUES (2);
ROLLBACK TO SAVEPOINT my_savepoint;
INSERT INTO my_table VALUES (3);
COMMIT;


华夏公益教科书