海山数据库(He3DB)源码解读:BEGIN-END-ABORT

# 海山数据库(He3DB)源码详解:事务块执行过程及内核函数

本文介绍了事务执行过程中,从BEGIN事务开始到事务结束END/ABORT的内核函数执行过程。

前言:

事务SQL语句的执行过程,会先通过事务块函数修改事务块状态,然后根据事务块状态执行不同的事务行为。因此,本章会讲解事务块的开始和结束过程的事务块函数。

事务块控制事务执行的过程:

在讲具体函数之前,有必要在此讲解一下,事务块是如何控制事务行为的。事务管理器中,事务块会根据当前事务状态,来控制具体的事务操作行为,具体流程如下:

在这里插入图片描述

  • 开始事务块:表示一个新的事务块的开始。
  • 检查事务状态:检查当前事务的状态,是否活跃、空闲或处于错误状态。
    • 活跃:如果事务处于活跃状态,执行事务操作。
      • 执行事务操作:执行具体的事务操作,如插入、更新或删除数据。
    • 空闲:如果事务处于空闲状态,等待操作命令。
      • 等待操作命令:在事务空闲时等待接收到新的操作命令。
      • 接收到操作命令:一旦接收到操作命令,开始执行事务操作。
    • 执行事务操作:执行具体的事务操作,如插入、更新或删除数据。
      • 操作成功?:检查事务操作是否成功。
      • 提交事务:如果操作成功,提交事务。
      • 回滚事务:如果操作失败或事务处于错误状态,回滚事务。
    • 错误:如果事务处于错误状态,进行回滚操作。
      • 回滚事务:如果操作失败或事务处于错误状态,回滚事务。
  • 结束事务块:表示事务块的结束,此时事务已经提交或回滚。

如何进行事务块操作:

使用 BEGIN 命令可以手动控制启动事务的边界,开始一个新的事务块;
使用 END \COMMIT 命令可以手动控制结束事务,结束一个执行中的事务块;
使用 ABORT \ ROLLBACK 命令可以手动控制放弃回滚事务,结束一个出错的事务块;
当执行这些SQL语句时,系统底层会调用相对应的事务块函数,来修改当前事务块的状态,从而控制具体的事务操作行为。其中,事务块操作的开始和结束分别对应的函数为:

  1. BEGIN 对应的事务块函数为 BeginTransactionBlock() 函数;
  2. END \ COMMIT 对应的事务块函数为 EndTransactionBlock() 函数;
  3. ABORT \ ROLLBACK 对应的事务块函数为 UserAbortTransactionBlock() 函数。
    那么,这些函数的执行流程是什么样的?

BeginTransactionBlock()函数的执行过程:

当终端输入BEGIN或者START TRANSACTION命令时,会开始一个事务块。处理过程首先会调用BeginTransactionBlock()函数。该函数内部主体为一个switch结构,会对枚举类型TBlockState中的所有状态都进行一个判断,并作一个对应的处理。执行过程示意图如下:

在这里插入图片描述

  1. 首先通过全局变量CurrentTransactionState获得当前事务块状态的变量;

     TransactionState s = CurrentTransactionState;
    
  2. 然后通过switch-case结构,根据当前事务块状态做对应的操作,其中有包括:

  • 如果当前事务块状态为TBLOCK_STARTED,则修改为TBLOCK_BEGIN;
        case TBLOCK_STARTED:
    		s->blockState = TBLOCK_BEGIN;
    		break;
    
  • 如果当前事务块状态为TBLOCK_IMPLICIT_INPROGRESS,则修改为TBLOCK_BEGIN;
        case TBLOCK_IMPLICIT_INPROGRESS:
    		s->blockState = TBLOCK_BEGIN;
    		break;
    
  • 如果当前事务块状态为TBLOCK_INPROGRESS、TBLOCK_PARALLEL_INPROGRESS、TBLOCK_SUBINPROGRESS、TBLOCK_ABORT和TBLOCK_SUBABORT,会进行WARNING报警,但是不会影响执行过程,可以继续执行;
        case TBLOCK_INPROGRESS:
    	case TBLOCK_PARALLEL_INPROGRESS:
    	case TBLOCK_SUBINPROGRESS:
    	case TBLOCK_ABORT:
    	case TBLOCK_SUBABORT:
    		ereport(WARNING,
    				(errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
    				 errmsg("there is already a transaction in progress")));
    		break;
    
  • 如果当前事务块状态为上述提到的其他状态,则直接报FATAL错误,直接退出事务块过程;
        case TBLOCK_DEFAULT:
    	case TBLOCK_BEGIN:
    	case TBLOCK_SUBBEGIN:
    	case TBLOCK_END:
    	case TBLOCK_SUBRELEASE:
    	case TBLOCK_SUBCOMMIT:
    	case TBLOCK_ABORT_END:
    	case TBLOCK_SUBABORT_END:
    	case TBLOCK_ABORT_PENDING:
    	case TBLOCK_SUBABORT_PENDING:
    	case TBLOCK_SUBRESTART:
    	case TBLOCK_SUBABORT_RESTART:
    	case TBLOCK_PREPARE:
    		elog(FATAL, "BeginTransactionBlock: unexpected state %s",
    			 BlockStateAsString(s->blockState));
    		break;
    

以上,就是BeginTransactionBlock()函数的全部执行过程。

EndTransactionBlock()函数的执行过程:

当终端输入COMMIT或者EDN语句时,这时一个事务块会发起提交或者结束,如果输入END,正确结束为提交,错误结束为回滚。处理过程首先会调用EndTransactionBlock()函数,并根据返回值判断是否时错误结束发生回滚。EndTransactionBlock()函数和BeginTransactionBlock()十分相似,内部主要是一个swith结构,这里直接说执行流程:

在这里插入图片描述

  1. 首先通过全局变量CurrentTransactionState获得当前事务块状态的变量,并定义返回值bool变量result;

     TransactionState s = CurrentTransactionState;
     bool		result = false;
    
  2. 然后通过switch-case结构,根据当前事务块状态做对应的操作,其中有包括:

  • 如果当前事务块状态为TBLOCK_INPROGRESS,则修改为TBLOCK_END,并将变量result赋值为true;
     case</
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值