海山数据库(He3DB)源码详解:子事务清理函数
该函数会在AbortSubTransaction函数之后执行,二者共同完成子事务的中止和清理操作。
执行条件
-
在终端主动执行ABORT语句,终止事务会在CommitTransactionCommand函数中调用CleanupSubTransaction函数;
-
在隐式事务中执行SQL语句发生错误时,底层源码会跳回PostgresMain函数中并调用AbortCurrentTransaction函数,终止事务并调用CleanupSubTransaction函数。
以下是CleanupSubTransaction函数的执行流程图:

- 开始:流程的开始。
- 获取当前事务状态:获取
CurrentTransactionState以获取当前事务的状态。 - 显示事务状态:调用
ShowTransactionState函数,显示当前事务状态。 - 检查事务状态:检查当前事务状态是否不是
TRANS_ABORT。 - 不是TRANS_ABORT:如果当前事务状态不是
TRANS_ABORT,则记录一条警告日志,说明当前状态。 - 是TRANS_ABORT:如果当前事务状态是
TRANS_ABORT,继续执行子事务的清理流程。 - 清理子事务门户:调用
AtSubCleanup_Portals函数,清理子事务的门户(portals)。 - 设置当前资源所有者:将当前资源所有者设置为父事务的资源所有者。
- 删除子事务资源所有者:如果子事务有自己的资源所有者,调用
ResourceOwnerDelete函数进行删除。 - 清理内存:调用
AtSubCleanup_Memory函数,进行内存方面的清理。 - 设置事务状态为TRANS_DEFAULT:将事务状态设置为
TRANS_DEFAULT,表示子事务已清理。 - 弹出当前事务:调用
PopTransaction函数,从事务堆栈中弹出当前子事务。 - 结束:流程结束。
执行过程
1. 开始清理事务
获取当前事务状态并检查。
TransactionState s = CurrentTransactionState;
ShowTransactionState("CleanupSubTransaction");
if (s->state != TRANS_ABORT)
elog(WARNING, "CleanupSubTransaction while in %s state",
TransStateAsString(s->state));
-
从全局变量中获得需要终止的事务状态,并记录一条CleanupSubTransaction日志;
-
检查当前状态,如果不为TRANS_ABORT调用elog函数记录一条WARNING日志。
2. 清理游标资源
清理子事务创建的所有游标资源。
AtSubCleanup_Portals(s->subTransactionId);
删除子事务失败时创建的所有门户,但注意 不会放弃任何已重新分配给父节点的游标。
3. 清理资源拥有者相关
将父节点移交给全局变量,并释放当前事务资源拥有者。
CurrentResourceOwner = s->parent->curTransactionOwner;
CurTransactionResourceOwner = s->parent->curTransactionOwner;
if (s->curTransactionOwner)
ResourceOwnerDelete(s->curTransactionOwner);
s->curTransactionOwner = NULL;
-
将父节点的curTransactionOwner移交给全局变量CurrentResourceOwner和CurTransactionResourceOwner;
-
如果子事务curTransactionOwner存在,调用ResourceOwnerDelete()函数释放子事务curTransactionOwner资源,并将其置为NULL。
4. 清理内存上下文
将内存上下文切换到父节点,并释放子节点内存上下文。
AtSubCleanup_Memory();
-
调用AtSubCleanup_Memory()函数将全局变量CurTransactionContext切换到父节点的curTransactionContext;
-
如果TransactionAbortContext存在,清理内存留出空间以备之后使用;
-
删除子事务的curTransactionContext,并将其置为NULL。
5. 完成子事务清理
恢复事务的默认状态并从事务链栈弹出子事务。
s->state = TRANS_DEFAULT; PopTransaction();
-
将事务状态修改为TRANS_DEFAULT,恢复默状态;
-
从事务链栈中弹出子事务,并将顶部事务状态修改为父节点状态。
作者介绍
李超,移动云数据库工程师,负责云原生数据库He3DB的研发。




