openGauss源码解析(69)

openGauss源码解析:事务机制源码解析(1)

5.2 事务并发控制

事务并发控制机制用来保证并发执行事务的情况下openGauss的ACID特性。下面将逐一介绍事务并发控制的各组成部分。

5.2.1 事务状态机

openGauss将事务系统分为上层(事务块TBlockState)以及底层(TransState)两个层次。

通过分层的设计,在处理上层业务时可以屏蔽具体细节,实现灵活支持客户端各类事务执行语句(BEGIN/START TRANSACTION/COMMIT/ROLLBACK/END)。

(1) 事务块TBlockState:客户端query的状态,用于提高用户操作数据的灵活性,用事务块的形式支持在一个事务中执行多条query语句。
(2) 底层事务TransState:内核端视角,记录了整个事务当前处于的具体状态。

1. 事务上层状态机

事务块上层状态机结构体代码如下:

typeset enum TBlockState

{

/* 不在事务块中的状态:单条SQL语句 */

TBLOCK_DEFAULT,/* 事务块缺省状态 */

TBLOCK_STARTED,/*执行单条query 语句*/

/* 处于事务块中的状态:一个事务包含多条语句 */

TBLOCK_BEGIN,/* 遇到事务开始命令BEGIN/START TRANSACTION */

TBLOCK_INPROGRESS,/* 表明正在事务块处理过程中*/

TBLOCK_END,/ *遇到事务结束命令END/COMMIT */

TBLOCK_ABORT,/* 事务块内执行报错,等待客户端执行ROLLBACK */

TBLOCK_ABORT_END,/ *在事务块内执行报错后,接收客户端执行ROLLBACK */

TBLOCK_ABORT_PENDING,/* 事务块内执行成功,接收客户端执行ROLLBACK(期望事务回滚)*/

TBLOCK_PREPARE,/ *两阶段提交事务,收到PREPARE TRANSACTION命令*/

/* 子事务块状态,与上述事务块状态类似 */

TBLOCK_SUBBEGIN,/* 遇到子事务开始命令SAVEPOINT */

TBLOCK_SUBINPROGRESS,/* 表明正在子事务块处理过程中*/

TBLOCK_SUBRELEASE,/* 遇到子事务结束命令RELEASE SAVEPOINT */

TBLOCK_SUBCOMMIT,/* 遇到事务结束命令END/COMMIT 从最底层的子事务递归的提交到最顶层事务*/

TBLOCK_SUBABORT,/* 子事务块内执行报错,等待客户端ROLLBACK TO/ROLLBACK */

TBLOCK_SUBABORT_END,/* 在子事务块内执行报错后,接收到客户端ROLLBACK TO上层子事务/ROLLBACK */

TBLOCK_SUBABORT_PENDING,/* 子事务块内执行成功,接收客户端执行的ROLLBACK TO上层子事务/ROLLBACK */

TBLOCK_SUBRESTART,/* 子事务块内执行成功,收到ROLLBACK TO当前子事务*/

TBLOCK_SUBABORT_RESTART/* 子事务块内执行报错后,接收到ROLLBACK TO当前子事务*/

} TBlockState;

为了便于理解,可以先不关注子事务块的状态。当理解了主事务的状态机行为后,子事务块的状态机转换同父事务类似。父子事务的关系类似于一个栈的实现,父事务的子事务相较于父事务后开始先结束。

显式事务块的状态机及相应的转换函数如图5-2所示。

图5-2 事务块状态机

图5-2中的事务状态相对应的事务状态机结构体中的值如表5-1所示。

表5-1 事务块状态

事务状态

事务状态机结构体

默认

TBLOCK_DEFAULT

已开始

TBLOCK_STARTED

事务块开启

TBLOCK_BEGIN

事务块运行中

TBLOCK_INPROGRESS

事务块结束

TBLOCK_END

回滚

TBLOCK_ABORT

回滚结束

TBLOCK_ABORT_END

回滚等待

TBLOCK_ABORT_PENDING

在无异常情形下,一个事务块的状态机如图5-2所示按照默认(TBLOCK_DEFAULT)->已开始(TBLOCK_STARTED)->事务块开启(TBLOCK_BEGIN)->事务块运行中(TBLOCK_INPROGRESS)->事务块结束(TBLOCK_END)->默认(TBLOCK_DEFAULT)循环。剩余的状态机是在上述正常场景下的各个状态点的异常处理分支。

(1) 在进入事务块运行中(TBLOCK_INPROGRESS)之前出错,因为事务还没有开启,直接报错并回滚,清理资源回到默认(TBLOCK_DEFAULT)状态。
(2) 在事务块运行中(TBLOCK_INPROGRESS)出错分为2种情形。事务执行失败:事务块运行中(TBLOCK_INPROGRESS)->回滚(TBLOCK_ABORT)->回滚结束(TBLOCK_ABORT_END)->默认(TBLOCK_DEFAULT);用户手动回滚执行成功的事务:事务块运行中(TBLOCK_INPROGRESS)->回滚等待(TBLOCK_ABORT_PENDING)->默认(TBLOCK_DEFAULT)。
(3) 在用户执行COMMIT语句时出错:事务块结束(TBLOCK_END)->默认(TBLOCK_DEFAULT)。由图5-2可以看出,事务开始后离开默认(TBLOCK_DEFAULT)状态,事务完全结束后回到默认(TBLOCK_DEFAULT)状态。
(4) openGauss同时还支持隐式事务块,当客户端执行单条SQL语句时可以自动提交,其状态机相对比较简单:按照默认(TBLOCK_DEFAULT)->已开始(TBLOCK_STARTED)->默认(TBLOCK_DEFAULT)循环。
posted @ 2024-04-30 09:52  openGauss-bot  阅读(8)  评论(0编辑  收藏  举报