子事务是在事务内部启动的,允许将大型事务分解为较小的单元。 子事务可以提交或中止而不影响其父事务,从而允许父事务继续。 这使得错误处理更加容易,这是一个常见的应用程序开发模式。 子事务这个词通常缩写为子事务。
子事务可以通过SAVEPOINT
命令显式启动,但也可以通过其他方式启动,
例如PL/pgSQL的EXCEPTION
子句。PL/Python和PL/Tcl也支持显式子事务。
子事务也可以从其他子事务中启动。顶层事务及其子事务形成一个层次结构或树状结构,
这就是为什么我们将主事务称为顶层事务。
如果一个子事务被分配了一个非虚拟事务ID, 那么它的事务ID被称为“子事务ID”。 只读子事务不会被分配子事务ID,但一旦它们尝试写入, 它们将会被分配一个。这也会导致所有子事务ID的父事务, 包括顶级事务在内,都被分配非虚拟事务ID。 我们确保父事务ID总是小于其任何子事务ID。
每个子事务的直接父事务ID记录在pg_subtrans
目录中。
顶级事务ID没有父事务,因此不会为其创建条目,也不会为只读子事务创建条目。
当一个子事务提交时,所有带有子事务ID的已提交子事务也会在该事务中被视为 子提交状态。当一个子事务中止时,所有的子事务也会被视为中止状态。
当一个具有xid的顶级事务提交时,其所有已子提交的子事务也会被持久性地记录为已提交,
存储在pg_xact
子目录中。如果顶级事务中止,其所有子事务也会中止,
即使它们已经被子提交。
每个事务保持的子事务越多(未回滚或释放),事务管理的开销就越大。
每个后端最多可以在共享内存中缓存64个打开的子事务ID;超过这个点后,
由于在pg_subtrans
中额外查找子事务ID条目的原因,
存储I/O开销会显著增加。