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 ,这样每个会话都可以有一个等待中的预备事务。