本文介绍了PREPARE TRANSACTION的语法、参数以及示例等内容。
简介
PREPARE TRANSACTION
为两阶段提交准备当前事务。在这个命令之后,该事务不再与当前会话关联。相反,它的状态被完全存储在磁盘上,并且有很高的可能性它会被提交成功(即便在请求提交前发生数据库崩溃)。
一旦被准备好,事务稍后就可以分别用 COMMIT PREPARED 或者ROLLBACK PREPARED提交或者回滚。可以从任何会话而不仅仅是执行原始事务的会话中发出这些命令。
从发出命令的会话的角度来看,PREPARE TRANSACTION
不像ROLLBACK
命令: 在执行它之后,就没有活跃的当前事务,并且该预备事务的效果也不再可见( 如果该事务被提交,效果将重新变得可见)。
如果由于任何原因PREPARE TRANSACTION
命令失败,它会变成一个ROLLBACK
:当前事务会被取消。
语法
PREPARE TRANSACTION transaction_id
参数
transaction_id
一个任意的事务标识符, COMMIT PREPARED
或者ROLLBACK PREPARED
以后将用这个标识符来标识这个事务。该标识符必须写成一个字符串, 并且长度必须小于 200 字节。它也不能与任何当前已经准备好的事务的标识符相同。
说明
PREPARE TRANSACTION
并不是设计为在应用或者交互式会话中使用。它的目的是允许一个外部事务管理器在多个数据库或者其他事务性来源之间执行原子的全局事务。除非你在编写一个事务管理器,否则你可能不会用到PREPARE TRANSACTION
。
这个命令必须在一个事务块中使用。事务块用BEGIN开始。
当前在已经执行过任何涉及到临时表或者会话的临时命名空间、创建带 WITH HOLD
的游标或者执行 LISTEN
、UNLISTEN
或NOTIFY
的事务中,不允许PREPARE
该事务。这些特性与当前会话绑定得太过紧密,所以对一个要被准备的事务来说没有什么用处。
如果用SET
(不带LOCAL
选项)修改过事务的任何运行时参数,这些效果会持续到 PREPARE TRANSACTION
之后,并且将不会被后续的任何 COMMIT PREPARED
或 ROLLBACK PREPARED
所影响。因此,在这一方面PREPARE TRANSACTION
的行为更像 COMMIT
而不是ROLLBACK
。
所有当前可用的准备好事务被列在pg_prepared_xacts
系统视图中。
让一个事务处于准备好状态太久是不明智的。这将会干扰 VACUUM
回收存储的能力,并且在极限情况下可能导致数据库关闭以阻止事务 ID 回卷。还要记住,该事务会继续持有它已经持有的锁。该特性的设计用法是,只要一个外部事务管理器已经验证其他数据库也准备好了要提交,一个准备好的事务将被正常地提交或者回滚。
如果没有建立一个外部事务管理器来跟踪准备好的事务并且确保它们被迅速地结束,最好禁用准备好事务特性(设置 max_prepared_transactions 为零)。这将防止意外地创建准备好事务,不然该事务有可能被忘记并且最终导致问题。
示例
为两阶段提交准备当前事务,使用foobar
作为事务标识符:
PREPARE TRANSACTION 'foobar';