# 海山数据库(He3DB)源码详解:子事务块内核函数执行过程
本文介绍了子事务执行过程中,从SAVEPOINT定义子事务开始到子事务结束释放RELEASE或者回滚ROLLBACK To的内核函数执行过程。
处理TRANS_STMT_SAVEPOINT
当终端输入SAVEPOINT XX语句时,这时会发起一个子事务保存点定义的操作。首先会调用RequireTransactionBlock函数检查当前事务的状态,之后再调用DefineSavepoint函数启动一个子事务节点,加入到事务链栈中。
RequireTransactionBlock()函数执行过程:
RequireTransactionBlock()函数会调用CheckTransactionBlock()函数完成对事务状态的检查,具体的CheckTransactionBlock()函数执行过程如下:
- 调用IsTransactionBlock()检查全局结构体变量CurrentTransactionState中的blockState成员值,如果blockState等于TBLOCK_DEFAULT或者TBLOCK_STARTED,表示不存在事务块,返回false,其他返回true:
if (IsTransactionBlock())
return;
- 调用IsSubTransaction()检查全局结构体变量CurrentTransactionState中的nestingLevel成员值,如果≥2表示有子事务嵌套,返回true,否则返回false:
if (IsSubTransaction())
return;
- 判断当前事务是否为顶层事务,如果不是顶层事务直接返回退出。
if (!isTopLevel)
return;
- 如果以上检查都没有通过,则根据输入参数throwError的值输出ERROR错误还是WARING错误。
ereport(throwError ? ERROR : WARNING,
(errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
/* translator: %s represents an SQL statement name */
errmsg("%s can only be used in transaction blocks",
stmtType)));
DefineSavepoint()函数执行过程:
该函数和其他事务块操作函数十分相似,内部主要是一个swith结构,说执行流程如下:
- 通过全局状态变量获取当前事务状态,并检查是否为并行事务模式,如果时并行事务则直接报错。
TransactionState s = CurrentTransactionState;
/*
* Workers synchronize transaction state at the beginning of each
* parallel operation, so we can't account for new subtransactions
* after that point.
* (Note that this check will certainly error out if s->blockState
* is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid
* case below.)
*/
if (IsInParallelMode())
ereport(