PREPARE TRANSACTION为当前事务的两阶段提交做准备。在命令之后, 事务就不再和当前会话关联了;它的状态完全保存在磁盘上,它被提交成功的可能性非常高, 即使是在请求提交之前数据库发生了崩溃也如此。
一旦准备好了,一个事务就可以在稍后用COMMIT PREPARED或 ROLLBACK PREPARED命令分别进行提交或者回滚。 这些命令可以从任何会话中发出,而不光是最初执行事务的那个会话。
从发出命令的会话的角度来看,PREPARE TRANSACTION不同于ROLLBACK: 在执行它之后,就不再有活跃的当前事务了,并且预备事务的效果无法见到 (在事务提交的时候其效果会再次可见)。
如果PREPARE TRANSACTION因为某些原因失败, 那么它就会变成一个ROLLBACK,当前事务被取消。
一个任意的标识符,用于后面在COMMIT PREPARED或ROLLBACK PREPARED 的时候标识这个事务。这个标识符必须以字符串文本的方式书写,并且必须小于 200 字节长。 它不能和任何当前预备事务已经使用了的标识符同名。
PREPARE TRANSACTION不是为了在应用或交互会话中使用。 它的目的是允许外部的事务管理器实现多个数据库或者与其他事务源实现原子的全局事务。 除非你写一个事务管理器,否则你不应该使用PREPARE TRANSACTION。
这条命令必须在一个事务块里面使用。用BEGIN开始一个事务。
目前,不允许对那些执行了涉及临时表,或者是创建了带WITH HOLD游标, 或者执行了LISTEN或UNLISTEN的事务进行PREPARE。 这些特性和当前会话绑定得实在是太紧密了,因此在一个预备事务里没什么可用的。
如果事务用SET(没有LOCAL选项)修改了运行时参数, 这些效果在PREPARE TRANSACTION之后保留,并且不会被任何以后的 COMMIT PREPARED或ROLLBACK PREPARED所影响。 因此,在这方面,PREPARE TRANSACTION 表现得更像COMMIT而不是ROLLBACK。
所有目前可用的预备事务都在系统视图pg_prepared_xacts 里面列出。
小心 |
把一个事务长时间停在预备状态是不明智的:它会影响VACUUM回收存储的能力, 并且在极端情况可能导致数据库关闭以阻止包括事务ID(参阅第 23.1.5 节)。 还要记住,事务会继续持有它们持有的锁。 这个特性的用法是预备事务通常会在外部的事务管理器核实了其它数据库也准备好提交之后,提交或者回滚事务。 如果你还没有设置一个额外的事务管理器追踪预备事务和确保他们得到及时关闭, 最好通过设置max_prepared_transactions为0来保持预备事务特征不可用。 这将阻止意外的创建可能被遗忘和最终导致问题的预备事务。 |