当前位置: 首页 > news >正文

Postgresql源码(100)Portal与事务的关系(顶层事务与子事务)

1 总结

  • portal与事务有强绑定的关系,由portal->createSubid变量记录关联关系。如果为1表示顶层事务,关联的是子事务。

  • 不论是顶层事务还是子事务,提交、回滚时只会处理自己创建出来的portal。

    • 顶层事务会清理非活跃状态的Portal,如果Portal是活跃的会保留内存。
    • 子事务直接释放portal,无论是否活跃。
  • PLpgSQL中的提交回滚,有较大限制:

    • PLpgSQL中的提交或回滚,如果call proc在事务块中,直接失败。
    • PLpgSQL中的提交或回滚,如果pl带exception,直接失败。
    • 原因是,pl中的提交或回滚不能再子事务、或事务块内,要实现的话比较复杂,需要对齐SPI与子事务、portal与子事务、exprcontext与子事务等等。
  • 子事务ID只增不减,可能有空隙存在,参考PushTransaction的currentSubTransactionId。

2 提交

2.1 顶层事务提交:PreCommit_Portals与子事务提交AtSubCommit_Portals

实例

CREATE  OR REPLACE PROCEDURE tproc1() 
AS $$
DECLAREcurs1 refcursor;                       curs2 CURSOR FOR SELECT c1 FROM tf1;curs3 CURSOR (key integer) FOR SELECT * FROM tf1 WHERE c1 > key;x int;y tf1%ROWTYPE;
BEGINopen curs1 FOR SELECT * FROM tf1 WHERE c1 > 3;fetch curs1 into y; RAISE NOTICE 'curs1 : %', y.c3;fetch curs1 into y; RAISE NOTICE 'curs1 : %', y.c3;open curs2;fetch curs2 into x; RAISE NOTICE 'curs2 : %', x;fetch curs2 into x; RAISE NOTICE 'curs2 : %', x;OPEN curs3(4);  -- OPEN curs3(key := 4);fetch curs3 into y; RAISE NOTICE 'curs3 : %', y.c4;fetch curs3 into y; RAISE NOTICE 'curs3 : %', y.c4;
EXCEPTION WHEN others THENRAISE NOTICE 'in caller exception';
END;
$$ LANGUAGE plpgsql;begin;
savepoint sp1;
savepoint sp2;
call tproc1();
commit;

(1)第一次子事务提交:EXCEPTION子事务提交AtSubCommit_Portals(subid=4)

发生在call tproc1();执行完毕。

exec_stmt_blockReleaseCurrentSubTransactionCommitSubTransactionAtSubCommit_Portals

当前事务堆栈:

CurrentTransactionState->subTransactionId
[1,      2,          3,              4]|       |           |               |
top      savepoint   savepoint       exception

由于call进入SPI,当前SPI堆栈只有一层,对应到3号子事务上,因为是在3号子事务的背景下执行的CALL。_SPI_stack[0] = {connectSubid = 3}

AtSubCommit_Portals(mySubid=4) 开始处理portal:

portal1 = {          // 游标 mySubid = 4 ,当前游标的portal被继承给parent portalname = "<unnamed portal 17>", createSubid = 4,   // AtSubCommit_Portals 4-->3activeSubid = 4,createLevel = 4,   sourceText = "SELECT c1 FROM tf1",commandTag = CMDTAG_SELECT,strategy = PORTAL_ONE_SELECT}

… 三个游标的portal都是类似上面处理的。特殊的是顶层portal。不属于当前要释放的子事务4,不处理。

portal1 = {          // 顶层 mySubid = 3 ,当前不处理name = "", createSubid = 3, activeSubid = 3, createLevel = 3,   sourceText = "call tproc1();",commandTag = CMDTAG_CALL,strategy = PORTAL_MULTI_QUERY}

(2)第二次子事务提交:savepoint子事务提交AtSubCommit_Portals(subid=3)

发生在commit。

exec_simple_queryfinish_xact_commandCommitTransactionCommandCommitSubTransactionAtSubCommit_Portals

当前事务堆栈:

CurrentTransactionState->subTransactionId
[1,      2,          3]|       |           |
top      savepoint   savepoint

AtSubCommit_Portals(mySubid=3)开始处理portal:

portal1 = {          // 游标 mySubid = 4 ,当前游标的portal被继承给parent portalname = "<unnamed portal 17>", createSubid = 2,   // AtSubCommit_Portals 3-->2activeSubid = 2,   // AtSubCommit_Portals 3createLevel = 2,   // AtSubCommit_Portals 3-->2sourceText = "SELECT c1 FROM tf1",commandTag = CMDTAG_SELECT,strategy = PORTAL_ONE_SELECT}

当前堆栈Portal已经被drop了。现在PortalHashTable里面只有三个游标的Portal。

(3)第三次子事务提交:savepoint子事务提交(subid=2)

同上。

(4)顶层事务提交(subid=1)PreCommit_Portals

发生在commit。

exec_simple_queryfinish_xact_commandCommitTransactionCommandCommitTransactionPreCommit_Portals

提交时发现3个portal,只剩游标的3个portal了。

调用PortalDrop全部释放掉。

PreCommit_Portals函数需要关注的就是,普通portal都会被drop掉。特殊保留的是hold cursor即循环语句使用的内部自建游标,还有一种就是vacuum等多事务语句。

3 回滚

3.1 顶层事务清理:AtAbort_Portals

调用位置

AbortTransaction → AtAbort_Portals

调用一次即可,用户清理顶层事务。

清理逻辑

  1. 遍历PortalHashTable,拿到所有CreatePortal创建出来的Portal(两种:执行器的portal和游标的portal)
  2. 标记portal状态failed,标记failed的内存会被释放掉。
    1. 情况一:elog FATAL 主动标记failed
    2. 情况二:状态是PORTAL_READY的portal
  3. 跳过一些portal,不处理。
    1. 情况一:createSubid=0 前一个事务的portal,不属于自己(!=1)。
    2. 情况二:portal->autoHeld == true 专门用于循环的游标(不是用户创建的,PL自用的)。

3.2 子事务清理:AtSubAbort_Portals

调用位置

AbortSubTransaction → AtSubAbort_Portals

有两种调用场景:

  1. 事务块内一次性rollback,递归多次AtSubAbort_Portals,提交所有子事务。
  2. 回滚到某一个检查点,递归指定次数AtSubAbort_Portals,只提交指定的几个子事务。

清理逻辑

  1. 遍历PortalHashTable,拿到所有CreatePortal创建出来的Portal(两种:执行器的portal和游标的portal)
  2. 判断创建归属:
    • 如果当前清理的子事务 与 portal的createSubid匹配,直接清理PORTAL_READY和PORTAL_ACTIVE状态的,包括删除内存。
    • 如果当前清理的子事务 与 portal的createSubid不匹配:
      • 判断使用归属,如果当前清理的子事务 与 portal的activeSubid匹配,说明不是当前子事务创建的,但是被当前子事务使用了,指标记failed但不做清理,不删除内存。

4 PushTransaction与PopTransaction函数

  • 启动子事务时需要将当前事务入栈,CurrentTransactionState换成子事务的。
  • 子事务和父事务由parent连接。
  • 修改这部分代码需要注意一次弹出多个事务时,currentSubTransactionId有没有正确维护。
static void
PushTransaction(void)
{TransactionState p = CurrentTransactionState;TransactionState s;s = (TransactionState)MemoryContextAllocZero(TopTransactionContext,sizeof(TransactionStateData));

注意currentSubTransactionId直增不减。pop时也不减少。

	currentSubTransactionId += 1;if (currentSubTransactionId == InvalidSubTransactionId){currentSubTransactionId -= 1;pfree(s);ereport(ERROR,(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),errmsg("cannot have more than 2^32-1 subtransactions in a transaction")));}/** We can now stack a minimally valid subtransaction without fear of* failure.*/s->fullTransactionId = InvalidFullTransactionId;	/* until assigned */s->subTransactionId = currentSubTransactionId;s->parent = p;s->nestingLevel = p->nestingLevel + 1;s->gucNestLevel = NewGUCNestLevel();s->savepointLevel = p->savepointLevel;s->state = TRANS_DEFAULT;s->blockState = TBLOCK_SUBBEGIN;GetUserIdAndSecContext(&s->prevUser, &s->prevSecContext);s->prevXactReadOnly = XactReadOnly;s->parallelModeLevel = 0;s->topXidLogged = false;CurrentTransactionState = s;}

相关文章:

Postgresql源码(100)Portal与事务的关系(顶层事务与子事务)

1 总结 portal与事务有强绑定的关系&#xff0c;由portal->createSubid变量记录关联关系。如果为1表示顶层事务&#xff0c;关联的是子事务。 不论是顶层事务还是子事务&#xff0c;提交、回滚时只会处理自己创建出来的portal。 顶层事务会清理非活跃状态的Portal&#xff…...

Java、JSP企业快信系统的设计与实现

技术&#xff1a;Java、JSP等摘要&#xff1a;计算机网络的出现到现在已经经历了翻天覆地的重大改变。因特网也从最早的供科学家交流心得的简单的文本浏览器发展成为了商务和信息的中心。到了今天&#xff0c;互联网已经成为了大量应用的首选平台&#xff0c;人们已经渐渐习惯了…...

1.2(完结)C语言进阶易忘点速记

1.大端存储&#xff1a;高权位数字放在低地址处&#xff0c;低权位数字放在高地指处。(以字节为单位) 2.小端存储&#xff1a;低权位数字放在低地址处&#xff0c;高权位数字放在高地址处。(以字节为单位) 3.变量(char类型)进行运算的时候一定要注意整形提升与截断&#xff0…...

雅思经验(十一)

写作&#xff1a;WRITINGTASK 2Governments should spend money on railways rather than roads.To what extent do you agree or disagree with this statement?Give reasons for your answer and include any relevant examples from your own knowledge or experience.思路…...

C++中的智能指针

1.RAII 与引用计数了解 Objective-C/Swift 的程序员应该知道引用计数的概念。引用计数这种计数是为了防止内存泄露而产生的。 基本想法是对于动态分配的对象&#xff0c;进行引用计数&#xff0c;每当增加一次对同一个对象的引用&#xff0c;那么引用对象的引用计数就会增加一次…...

LSTM已死,Transformer当立(LSTM is dead. Long Live Transformers! ):下

2017 年,Google 在论文 Attention is All you need 中提出了 Transformer 模型,其使用 Self-Attention 结构取代了在 NLP 任务中常用的 RNN 网络结构。而且实验也证明Transformer 在效果上已经完败传统的 RNN 网络。Transformer 的整体模型架构如下图所示。尽管它看起来还是很…...

OJ万题详解––[NOIP2004 提高组] 合并果子(C++详解)

目录 题目 分析 参考代码 题目 题目描述 一个果园里&#xff0c;多多已经将所有的果子打了下来&#xff0c;而且按果子的不同种类分成了不同的堆。多多决定把所有的果子合成一堆。 每一次合并&#xff0c;多多可以把两堆果子合并到一起&#xff0c;消耗的体力等于两堆果子的…...

MySQL-字符集和比较规则

在计算机中只能存储二进制数据&#xff0c;那该怎么存储字符串呢&#xff1f;当然是建立字符与二进制数据的映射关系 了&#xff0c;建立这个关系最起码要搞清楚两件事&#xff1a; 界定清楚字符范围&#xff1a;需要把哪些字符映射成二进制数据&#xff1f;编码与解码&#x…...

微搭低代码从入门到精通12-网格布局

开发小程序首要的就是考虑布局的问题&#xff0c;我们在以前的版本只能选择普通容器结合图片和文本组件来构建页面。 使用通用组件布局也可以&#xff0c;但有个问题是你要先学习CSS&#xff0c;要懂布局的概念&#xff0c;比如需要知道啥是flex布局&#xff0c;然后还得熟悉每…...

【c语言】二叉树

主页&#xff1a;114514的代码大冒险 qq:2188956112&#xff08;欢迎小伙伴呀hi✿(。◕ᴗ◕。)✿ &#xff09; Gitee&#xff1a;庄嘉豪 (zhuang-jiahaoxxx) - Gitee.com 引入 我们之前已经学过线性数据结构&#xff0c;今天我们将介绍非线性数据结构----树 树是一种非线性的…...

六、Java框架之SpringBoot

黑马课程 文章目录1. SpringBoot入门1.1 SpringBoot入门案例步骤1&#xff1a;创建SpringBoot项目高版本springboot常见错误步骤2&#xff1a;创建BookController步骤3&#xff1a;启动服务器并运行程序pom.xml示例1.2 官网创建SpringBoot1.3 SpringBoot工程快速启动问题导入打…...

「Python|环境安装|Windows」如何在Windows上安装Python环境?

本文主要介绍如何在Windows上安装Python&#xff0c;帮助初学者或者非程序员伙伴快速搭建可以运行python代码的环境。 文章目录安装python做一点小配置验证python如何安装指定版本的python编程语言的环境搭建一直是学习编程的第一道门槛。 对于如何在Linux系统上安装指定版本的…...

人工智能轨道交通行业周刊-第33期(2023.2.6-2.12)

本期关键词&#xff1a;高铁激光清洗、高铁确认列车、无线通信系统、推理服务优化、量子信息技术 1 整理涉及公众号名单 1.1 行业类 RT轨道交通中关村轨道交通产业服务平台人民铁道世界轨道交通资讯网铁路信号技术交流北京铁路轨道交通网上榜铁路视点ITS World轨道交通联盟V…...

五分钟看懂Java字节码:极简手册

字节码新手很容易被厚厚的 JVM 书籍劝退&#xff0c;即使我看过相关书籍&#xff0c;工作真正用到时也全忘了&#xff0c;还得现学。 等我有了一定的字节码阅读经验&#xff0c;才发现字节码其实非常简单&#xff0c;只需要三步就能快速学会&#xff1a; 先了解 JVM 的基本结…...

C++ 类与对象(下)

✅<1>主页&#xff1a;我的代码爱吃辣 &#x1f4c3;<2>知识讲解&#xff1a;C &#x1f525;<3>创作者&#xff1a;我的代码爱吃辣 ☂️<4>开发环境&#xff1a;Visual Studio 2022 &#x1f4ac;<5>前言&#xff1a;C类与对象的收尾工作&#…...

Java基础——I/O

一、异常 异常是程序中可能出现的问题&#xff0c;它的父类是Exception。异常分为两类&#xff0c;编译时异常、运行时异常。 编译时异常&#xff1a;没有继承RuntimeException的异常&#xff0c;直接继承于Exception。编译阶段就会错误提示。运行时异常&#xff1a;RuntimeE…...

关于@hide的理解

在上一篇文章《学习HandlerThread》我们提到虽然HandlerThread类里有getThreadHandler()方法得到Handler&#xff0c;但是我们不可能调用到它。因为这个方法用hide注释了 /*** return a shared {link Handler} associated with this thread* hide*/NonNullpublic Handler getT…...

使用python加密主机文件几种方法实现

本文主要介绍了使用python加密主机文件几种方法实现&#xff0c;文中通过示例代码介绍的非常详细&#xff0c;对大家的学习或者工作具有一定的参考学习价值&#xff0c;需要的朋友们下面随着小编来一起学习学习吧数据加密是一种保护数据安全的技术&#xff0c;通过对数据进行编…...

西湖论剑 2023 比赛复现

WEB real_ez_node 在 route/index.js 中&#xff1a; router.post(/copy,(req,res)>{res.setHeader(Content-type,text/html;charsetutf-8)var ip req.connection.remoteAddress;console.log(ip);var obj {msg: ,}if (!ip.includes(127.0.0.1)) {obj.msg"only for…...

微信小程序更换管理员/重置管理员

方式1&#xff1a; 首先进入微信公众平台官网进入并登录后在管理中找到成员管理选项找到管理员点击后方的修改选项需要使用原管理员的微信进行扫码验证扫码后在手机上确认绑定新管理员&#xff0c;注意&#xff1a;如果是个人账号不可以更改成其他人。 方式2&#xff1a;原管…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

PHP和Node.js哪个更爽?

先说结论&#xff0c;rust完胜。 php&#xff1a;laravel&#xff0c;swoole&#xff0c;webman&#xff0c;最开始在苏宁的时候写了几年php&#xff0c;当时觉得php真的是世界上最好的语言&#xff0c;因为当初活在舒适圈里&#xff0c;不愿意跳出来&#xff0c;就好比当初活在…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命

在华东塑料包装行业面临限塑令深度调整的背景下&#xff0c;江苏艾立泰以一场跨国资源接力的创新实践&#xff0c;重新定义了绿色供应链的边界。 跨国回收网络&#xff1a;废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点&#xff0c;将海外废弃包装箱通过标准…...

页面渲染流程与性能优化

页面渲染流程与性能优化详解&#xff08;完整版&#xff09; 一、现代浏览器渲染流程&#xff08;详细说明&#xff09; 1. 构建DOM树 浏览器接收到HTML文档后&#xff0c;会逐步解析并构建DOM&#xff08;Document Object Model&#xff09;树。具体过程如下&#xff1a; (…...

ffmpeg(四):滤镜命令

FFmpeg 的滤镜命令是用于音视频处理中的强大工具&#xff0c;可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下&#xff1a; ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜&#xff1a; ffmpeg…...

自然语言处理——Transformer

自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效&#xff0c;它能挖掘数据中的时序信息以及语义信息&#xff0c;但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN&#xff0c;但是…...

06 Deep learning神经网络编程基础 激活函数 --吴恩达

深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...

2025季度云服务器排行榜

在全球云服务器市场&#xff0c;各厂商的排名和地位并非一成不变&#xff0c;而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势&#xff0c;对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析&#xff1a; 一、全球“三巨头”…...

华为OD机考-机房布局

import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...

日常一水C

多态 言简意赅&#xff1a;就是一个对象面对同一事件时做出的不同反应 而之前的继承中说过&#xff0c;当子类和父类的函数名相同时&#xff0c;会隐藏父类的同名函数转而调用子类的同名函数&#xff0c;如果要调用父类的同名函数&#xff0c;那么就需要对父类进行引用&#…...