子事务需要分配独立的事务 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;
让我们通过查询表元组的系统列 rowxid,rowtime,查看下各个子事务使用的事务 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。