PostgreSQL 中文参考文档
🌐 英文原版 官方 ↗

PREPARE TRANSACTION

PREPARE TRANSACTION — 为两阶段提交预备当前事务

Synopsis

PREPARE TRANSACTION transaction_id

描述

PREPARE TRANSACTION 为两阶段提交预备当前事务。在这个命令之后,该事务不再与当前会话相关联;取而代之的是,它的状态被完整地存储在磁盘上,即使在实际请求提交之前发生了数据库崩溃,它也有非常大的概率能够成功提交。

一旦被预备,事务之后就可以分别用 COMMIT PREPARED 或 ROLLBACK PREPARED 来提交或回滚。这些命令可以从任何会话发出,而不仅限于执行了原事务的那个会话。

从发出命令的会话的角度来看,PREPARE TRANSACTION 与 ROLLBACK 命令并无太大不同:执行它之后,就不再有活动的当前事务了,并且预备事务的效果也不再可见。(如果该事务被提交,这些效果将重新变为可见。)

如果 PREPARE TRANSACTION 命令由于任何原因而失败,它就变成了一次 ROLLBACK:当前事务被取消。

参数

transaction_id

一个任意的标识符,之后在 COMMIT PREPARED 或 ROLLBACK PREPARED 中用它来标识这个事务。该标识符必须写成一个字符串字面值,并且长度必须小于 200 字节。它不能与任何当前已预备事务所使用的标识符相同。

注记

PREPARE TRANSACTION 并不是为应用程序或交互式会话中的使用而设计的。它的目的是允许外部事务管理器跨多个数据库或其他事务性资源执行原子性的全局事务。除非你正在编写一个事务管理器,否则你可能不应该使用 PREPARE TRANSACTION。

这个命令必须在一个事务块内使用。请使用 BEGIN 来启动一个事务块。

目前不允许 PREPARE 这样的事务:它已经执行过任何涉及临时表或会话临时命名空间的操作、创建过任何 WITH HOLD 游标,或者执行过 LISTEN、UNLISTEN 或 NOTIFY。这些特性与当前会话绑定得太紧密,对于要被预备的事务来说没有什么用处。

如果该事务用 SET(不带 LOCAL 选项)修改过任何运行时参数,这些效果会在 PREPARE TRANSACTION 之后持续存在,并且不会受到之后任何 COMMIT PREPARED 或 ROLLBACK PREPARED 的影响。因此,仅就这一点而言,PREPARE TRANSACTION 的行为更像 COMMIT 而不是 ROLLBACK。

所有当前可用的预备事务都列在 pg_prepared_xacts 系统视图中。

Caution

让事务长时间停留在预备状态是不明智的。这会妨碍 VACUUM 回收存储空间,并且在极端情况下可能导致数据库关闭以防止事务 ID 回卷(参见 Section 24.1.5)。还请记住,该事务会继续持有它原本持有的所有锁。这个特性的预期用法是:一旦外部事务管理器确认其他数据库也已准备好提交,就尽快提交或回滚预备事务。

如果你还没有设置外部事务管理器来跟踪预备事务并确保它们被及时了结,那么最好通过把 max_prepared_transactions 设置为零来禁用预备事务功能。这可以防止意外创建预备事务,避免它们随后被遗忘并最终引发问题。

示例

使用 foobar 作为事务标识符,为两阶段提交预备当前事务:

PREPARE TRANSACTION 'foobar';

兼容性

PREPARE TRANSACTION 是 PostgreSQL 的一个扩展。它是为外部事务管理系统而设计的,其中一些系统已被标准(例如 X/Open XA)所覆盖,但这些系统的 SQL 部分并没有被标准化。

另请参阅

COMMIT PREPARED, ROLLBACK PREPARED