Redrock Postgres 文档
主页 切换暗/亮/自动模式 切换暗/亮/自动模式 切换暗/亮/自动模式 返回首页
编辑页面

子事务需要分配独立的事务 ID 吗?

问题描述

子事务,也称为“嵌套事务”,是在已启动事务范围内通过指令启动的事务。此功能允许用户部分回滚事务,这在许多情况下很有帮助:如果发生某些错误,需要重复的步骤更少,可以重试操作。

那么,子事务需要分配独立的事务 ID 吗?过多的子事务是否存在用尽事务 ID 的风险?

问题解答

Redrock Postgres 是基于撤消日志记录位置实现的子事务,这些子事务不过是事务执行过程中的一个临时标记,它们并不需要分配独立的事务 ID,不会对系统造成任何风险。

问题验证

使用子事务的情况如下:

  • SQL 命令SAVEPOINT在当前事务中定义一个新的保存点。
  • PL/pgSQL 过程中的代码块 BEGIN / EXCEPTION WHEN .. / END

下面我们启动一个事务块,在事务中使用SAVEPOINT创建多个子事务,在每个子事务中往表test1中插入一条数据。

CREATE TABLE test1(i integer);

BEGIN;

SELECT pg_current_xact_id();
 pg_current_xact_id
--------------------
           (6,15,1)

INSERT INTO test1 VALUES (1);
SAVEPOINT s1;
INSERT INTO test1 VALUES (2);
SAVEPOINT s2;
SAVEPOINT s3;
INSERT INTO test1 VALUES (3);
COMMIT;

让我们通过查询表元组的系统列 rowxidrowtime,查看下各个子事务使用的事务 ID。

SELECT ctid, rowxid, rowtime, i FROM test1;
 ctid  |  rowxid  | rowtime | i 
-------+----------+---------+---
 (0,1) | (6,15,1) |     946 | 1
 (0,2) | (6,15,1) |     946 | 2
 (0,3) | (6,15,1) |     946 | 3

在上面的例子中,我们会发现,子事务使用了和所属事务块同样的事务 ID,它们并不需要分配独立的事务 ID。