PolarDB-X 源码解读:事务的一生

本文深入解析PolarDB-X中事务的关键代码,包括事务开始、执行、提交的生命周期。文章通过两个示例展示事务在计算节点(CN)的行为,涉及连接管理、一阶段提交优化和分布式事务恢复。内容涵盖BEGIN、SELECT/UPDATE操作以及COMMIT的过程,强调了事务在多分片环境下的处理和事务恢复机制。
摘要由CSDN通过智能技术生成

概述

本文将主要解读 PolarDB-X 中事务部分的相关代码,着重解读事务的一生在计算节点(CN)中的关键代码:从开始、执行、到最后提交这一整个生命周期。

在阅读本文前,强烈推荐先阅读与 PolarDB-X 事务系统相关的文章:

以及此前发布的 PolarDB-X SQL 的一生

事务与连接

在 PolarDB-X 的 CN 层,与事务关系密切的是连接。这是因为数据节点(DN)也具备单个 DN 内的事务能力,CN 则通过与 DN 的连接来管理 DN 上的事务,从而实现强一致的分布式事务能力。其中涉及到的连接大致如下图所示:

先简单说一下这里面涉及的一些连接。ServerConnection 类似于前端连接,大部分的 SQL 语句执行的入口都是 ServerConnection#innerExecuteTConnection 中的 executeSQL 方法负责 SQL 语句的真正执行,也负责创建新的事务对象。TConnection 会一直引用着这个事务对象,直到事务提交或回滚。事务对象里有一个 TransactionConnectionHolder,负责管理该事务用到的所有物理连接(CN 连接 DN 的私有协议连接)。值得一提的是,ExecutionContext 作为一条逻辑 SQL 执行的上下文,也会引用这个事务对象。这样,后续执行器需要使用物理连接与 DN 通信时,就可以通过 ExecutionContext 拿到事务对象,再通过事务对象的 TransactionConnectionHolder 拿到合适的物理连接。

以上的各种连接,都会在下文继续讨论。

两个例子

接下来,我们以两个简单的例子,来说明事务的一生在 CN 的代码中是如何体现的。

测试用表:

CREATE TABLE `tb1` (
    `id` int PRIMARY KEY,
    `a` int
) DBPARTITION BY HASH(`id`)

先在里面插入几条数据:

INSERT INTO tb1 VALUES (0, 0), (1, 1), (2, 2), (3, 3);

测试使用的两个例子:

-- Example 1: 
BEGIN; 
SELECT * FROM tb1 WHERE id = 0; 
UPDATE tb1 SET a = 100 WHERE id = 1;
COMMIT;
-- Example 2: 
BEGIN; 
SELECT * FROM tb1 WHERE id = 0; 
UPDATE tb1 SET a = 101 WHERE id = 1;
UPDATE tb1 SET a = 101 WHERE id = 0;
COMMIT;

注意到例 2 只比 例 1 多修改了 id = 1 的数据。测试表是按 id 拆分的,因此 id = 0 和 id = 1 的记录会落在不同的物理分片上(假设分别为分片 0 和分片 1)。例 1 读了分片 0,写了分片 1,然后提交了事务,这将会触发我们对单分片写的“一阶段提交优化”。例 2 读了分片 0,随后写了分片 1 和 分片 0,然后提交了事务,这将会进行完整的分布式事务提交流程。这两个例子还会触发“只读连接优化”,即只有在第一次写的时候才真正开启分布式事务。

在接下来的讨论中,我们默认使用 TSO 事务策略和 RR 的隔离级别。

例 1 事务的一生

BEGIN

与 MySQL 类似,要开启一个事务,一般有两种方式。第一种方式是显式地执行 BEGIN 或 START TRANSACTION [transaction_characteristic],执行这两种语句,会调用 ServerConnection 中的 begin(boolean, IsolationLevel) 方法。第二种方式是执行 SET autocommit = 0,当前 session 会隐式开启事务,这种方式会调用 ServerConnection 中的 setAutocommit(boolean, boolean) 方法。两种方式都会调用 TConnection 的 setAutoCommit 方法。这些方法都只是简单地记录了一些变量(比如 transaction_characteristic 中设定的事务相关变量),同时标记这个连接开启了事务。此时,事务对象也还没创建出来,也没有与后端连接进行任何交互。

读分片 0

在开启事务后,执行 SELECT *

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值