海山数据库(He3DB)源码详解:两阶段提交(2PC)事务块内核函数执行过程

海山数据库(He3DB)源码详解:两阶段提交(2PC)事务块内核函数执行过程

本文介绍了两阶段提交(2PC)事务执行过程中,主要讲解事务的prepare阶段和commit阶段的内核函数执行过程。

前言

两阶段提交(2PC)是一种用于分布式系统的事务处理协议,旨在确保事务的原子性。以下是2PC从事务准备到提交或放弃的执行流程图:

graph TD
    A[开始] --> B[事务发起者请求所有参与者准备]
    B --> C{所有参与者是否准备好?}
    C -- 是 --> D[事务发起者发送提交请求]
    C -- 否 --> E[事务发起者发送放弃请求]
    D --> F{所有参与者是否同意提交?}
    F -- 是 --> G[所有参与者提交事务]
    F -- 否 --> H[所有参与者放弃事务]
    E --> I[所有参与者放弃事务]
    G --> J[事务提交完成]
    H --> J
    I --> J
    J --> K[结束]

流程说明:

  1. 开始:事务发起者(协调者)开始一个新的分布式事务。
  2. 事务发起者请求所有参与者准备:协调者向所有参与者发送准备请求,询问它们是否准备好提交事务。
  3. 所有参与者是否准备好?:这是一个决策点,需要等待所有参与者的响应。
    • :如果所有参与者都准备好了,协调者将发送提交请求。
    • :如果任何一个参与者没有准备好,协调者将发送放弃请求。
  4. 事务发起者发送提交请求:协调者向所有参与者发送提交事务的请求。
  5. 所有参与者是否同意提交?:这是另一个决策点,需要等待所有参与者的响应。
    • :如果所有参与者都同意提交,它们将执行提交操作。
    • :如果任何一个参与者拒绝提交,所有参与者将放弃事务。
  6. 所有参与者提交事务:参与者执行实际的提交操作,使事务永久生效。
  7. 所有参与者放弃事务:参与者执行回滚操作,撤销所有事务相关的更改。
  8. 事务提交完成:事务要么成功提交,要么被放弃,分布式事务到此结束。
  9. 结束:2PC过程完成。

在这里插入图片描述

处理TRANS_STMT_PREPARE

当终端输入PREPARE TRANSACTION xxx语句时,这时一个会发起2PC的事务提交准备过程。处理过程首先会调用PrepareTransactionBlock()函数,并根据返回值判断是否时错误结束发生回滚。

PrepareTransactionBlock()函数执行过程:

  1. 首先,该函数会调用EndTransactionBlock()函数,获得一个事务结束的返回值;
    TransactionState s;
	bool		result;

	/* Set up to commit the current transaction */
	result = EndTransactionBlock(false);
  1. 然后,判断result的值,如果为true,修改其他block的状态;如果为false,表示事务出错,准备进行回滚;
	if (result)
	{
		s = CurrentTransactionState;

		while (s->parent != NULL)
			s = s->parent;

		if (s->blockState == TBLOCK_END)
		{
			/* Save GID where PrepareTransaction can find it again */
			prepareGID = MemoryContextStrdup(TopTransactionContext, gid);

			s->blockState = TBLOCK_PREPARE;
		}
		else
		{
			/*
			 * ignore case where we are not in a transaction;
			 * EndTransactionBlock already issued a warning.
			 */
			Assert(s->blockState == TBLOCK_STARTED ||
				   s->blockState == TBLOCK_IMPLICIT_INPROGRESS);
			/* Don't send back a PREPARE result tag... */
			result = false;
		}
	}
  • 首先,获得当前事务的状态结构体,并找到事务的根节点;
  • 之后,判断节点的状态是否为END,如果是,则将当前的gid深拷贝一份,交给全局静态变量prepareGID,并修改事务块的状态为TBLOCK_PREPARE;否则,将返回结构result改为false,准备进行回滚。

根据PrepareTransactionBlock()返回值对事务进行标记

如果PrepareTransactionBlock()函数的返回值为false,则会将事务标记为CMDTAG_ROLLBACK,这意味着当前的事务将被中止,并且事务所作的所有更新都会被丢弃,回到事务开始之前的状态。调用SetQueryCompletion()函数对传入参数qc进行修改,完成事务的标记。

处理TRANS_STMT_COMMIT_PREPARED

当终端输入COMMIT PREPARED xxx语句时,这时会发起一个2PC的事务提交过程。处理过程首先会调用PreventInTransactionBlock()函数,检查当前分

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值