PREPARE TRANSACTION 为当前事务的两阶段提交做准备。 在命令之后,事务就不再和当前会话关联了;它的状态完全保存在磁盘上, 它提交成功有非常高的可能性,即使是在请求提交之前数据库发生了崩溃也如此。
一旦准备好了,一个事务就可以在稍后用 COMMIT PREPARED 或者 ROLLBACK PREPARED 命令分别进行提交或者回滚。 这些命令可以从任何会话中发出,而不光是执行最初的事务的那个会话。
从发出命令的会话的角度来看,PREPARE TRANSACTION 与 ROLLBACK 命令不无想象:在执行它之后,就不再有活跃的当前事务了,并且准备好的事务的效果无法见到。 (在事务提交的时候其效果会再次可见。)
如果因为任何原因 PREPARE TRANSACTION 命令失败, 那么它就会变成一个ROLLBACK:当前事务被取消。
一个任意的标识符,用于后面在 COMMIT PREPARED 或者 ROLLBACK PREPARED 的时候标识这个事务的。这个标识符必须以字串文本的方式写,并且必须小于 200 字节长。 它不能和任何当前准备好的事务已经使用的标识符同名。
这条命令必须在一个事务块里面使用。用 BEGIN 开始一个事务。
目前,不允许对那些执行了涉及临时表或者是创建了带 WITH HOLD 游标的事务进行 PREPARE。 这些特性和当前会话绑定得实在是太紧密了,因此在一个准备好的事务里没什么可用的。
如果事务用 SET 修改了运行时参数,这些效果在 PREPARE TRANSACTION 之后保留,并且不会被任何以后的 COMMIT PREPARED 或 ROLLBACK PREPARED 所影响。因此,在这方面,PREPARE TRANSACTION 表现得更像 COMMIT 而不是 ROLLBACK。
所有目前可用的准备好事务都在系统视图 pg_prepared_xacts 里面列出。
从性能的角度来看,把一个事务长时间停在准备好的状态是不明智的:它会影响 VACUUM 回收存储的能力。还要记住,事务会继续持有它们保持得锁。 这个特性的用法是准备好的事务通常会在外部的事务管理器核实了其他数据库也准备好提交之后,提交或者回滚事务。
如果你非常严肃地使用准备好事务,你可能需要增大 max_prepared_transactions 的数值, 因为缺省的设置太小(以避免浪费那些不需要它的用户的资源)。我们建议至少将其设置为等于 max_connections,这样每个会话都可以有一个等待中的准备好事务。