MogDB存储过程事务控制与异常块
点击蓝字
关注我们
本文将分别在openGauss/MogDB和PostgreSQL数据库中测试存储过程commit与exception的使用。
实验一
1.PostgreSQL
先创建测试表:
create table t1(id int);
下面创建存储过程proc1:
create or replace procedure proc1() as
$$
declare
beginraise notice '--begin to drop table t2,time=%',clock_timestamp();drop table if exists t2;raise notice '--drop table t2,time=%',clock_timestamp();raise notice '--begin to alter table t1 rename to t2,time=%',clock_timestamp(); alter table t1 rename to t2;raise notice '--alter table t1 rename to t2,time=%',clock_timestamp(); raise notice '--do something...,time=%',clock_timestamp(); perform pg_sleep(30);raise notice '--begin to commit,time=%',clock_timestamp();commit;raise notice '-- commit over,time=%',clock_timestamp();raise notice 'job is over,time=%',clock_timestamp();
end;
$$ language plpgsql;
完整的执行结果如下:
postgres=# call proc1();
NOTICE: --begin to drop table t2,time=2021-12-22 17:11:52.746994+08
NOTICE: table "t2" does not exist, skipping
NOTICE: --drop table t2,time=2021-12-22 17:11:52.747054+08
NOTICE: --begin to alter table t1 rename to t2,time=2021-12-22 17:11:52.747057+08
NOTICE: --alter table t1 rename to t2,time=2021-12-22 17:11:52.74728+08
NOTICE: --do something...,time=2021-12-22 17:11:52.74729+08
NOTICE: --begin to commit,time=2021-12-22 17:12:22.778001+08
NOTICE: -- commit over,time=2021-12-22 17:12:22.778074+08
NOTICE: job is over,time=2021-12-22 17:12:22.778081+08
CALL
Time: 30031.268 ms (00:30.031)
上面的程序代码块里,我们使用commit语句是为了确保t1表的改名操作可以立即对其它客户端可见,同时为了便于测试观察,我们在commit语句之前加了一个30秒的延时。
下面观察如果在这个延迟的时间内,如果有新的客户端访问t1表,是什么现象,测试结果如下图:
可以看到新的客户端访问t1表会发生锁等待(截图中的左下和右下部分)。
2.openGauss/MogDB
先创建测试表:
create table t1(id int);
下面创建存储过程proc1:
create or replace procedure proc1() as
beginraise notice '--begin to drop table t2,time=%',clock_timestamp();drop table if exists t2;raise notice '--drop table t2,time=%',clock_timestamp();raise notice '--begin to alter table t1 rename to t2,time=%',clock_timestamp(); alter table t1 rename to t2;raise notice '--alter table t1 rename to t2,time=%',clock_timestamp(); raise notice '--do something...,time=%',clock_timestamp(); perform pg_sleep(30);raise notice '--begin to commit,time=%',clock_timestamp();commit;raise notice '-- commit over,time=%',clock_timestamp();raise notice 'job is over,time=%',clock_timestamp();
end;
/
完整的执行结果如下:
postgres=# call proc1();
NOTICE: --begin to drop table t2,time=2021-12-22 17:37:40.72122+08
NOTICE: table "t2" does not exist, skipping
CONTEXT: SQL statement "drop table if exists t2"
PL/pgSQL function proc1() line 4 at SQL statement
NOTICE: --drop table t2,time=2021-12-22 17:37:40.721364+08
NOTICE: --begin to alter table t1 rename to t2,time=2021-12-22 17:37:40.721404+08
NOTICE: --alter table t1 rename to t2,time=2021-12-22 17:37:40.721835+08
NOTICE: --do something...,time=2021-12-22 17:37:40.721917+08
NOTICE: --begin to commit,time=2021-12-22 17:38:10.723386+08
NOTICE: -- commit over,time=2021-12-22 17:38:11.072483+08
NOTICE: job is over,time=2021-12-22 17:38:11.072545+08
程序代码块里使用commit语句是为了确保t1表的改名操作可以立即对其它客户端可见,为了便于测试观察,我们在commit语句之前加了一个30秒的延时。
下面观察如果在这个延迟的时间内,如果有新的客户端访问t1表,是什么现象,测试结果如下图:
可以看到新的客户端访问t1表会发生锁等待(截图中的左下和右下部分)。
实验二
对上面的proc1增加exception处理,修改后的代码如下:
1.PostgreSQL
先创建测试表:
create table t1(id int);
下面创建存储过程proc2:
create or replace procedure proc2() as
$$
declare
beginraise notice '--begin to drop table t2,time=%',clock_timestamp();drop table if exists t2;raise notice '--drop table t2,time=%',clock_timestamp();raise notice '--begin to alter table t1 rename to t2,time=%',clock_timestamp(); alter table t1 rename to t2;raise notice '--alter table t1 rename to t2,time=%',clock_timestamp(); raise notice '--do something...,time=%',clock_timestamp(); perform pg_sleep(30);raise notice '--begin to commit,time=%',clock_timestamp();commit;raise notice '-- commit over,time=%',clock_timestamp();raise notice 'job is over,time=%',clock_timestamp();exception when others thenraise notice 'sqlstate=%,sqlerrm=%', sqlstate,sqlerrm;
end;
$$ language plpgsql;
完整的执行结果如下:
postgres=# call proc2();
NOTICE: --begin to drop table t2,time=2021-12-22 17:48:56.030816+08
NOTICE: --drop table t2,time=2021-12-22 17:48:56.031055+08
NOTICE: --begin to alter table t1 rename to t2,time=2021-12-22 17:48:56.031082+08
NOTICE: --alter table t1 rename to t2,time=2021-12-22 17:48:56.031242+08
NOTICE: --do something...,time=2021-12-22 17:48:56.031269+08
NOTICE: --begin to commit,time=2021-12-22 17:49:26.09492+08
NOTICE: sqlstate=2D000,sqlerrm=cannot commit while a subtransaction is active
CALL
Time: 30064.663 ms (00:30.065)
可以看出,如果我们的语句块里有exception子句,那当我们调用commit语句则会提示错误:
cannot commit while a subtransaction is active
其实在官方文档有如下相关的描述:
A transaction cannot be ended inside a block with exception handlers.
参考链接如下:https://www.postgresql.org/docs/current/plpgsql-transactions.html
因此在PG里面,我们不能再有exception子句的存储过程使用commit或者rollback语句。
2.openGauss/MogDB
先创建测试表:
create table t1(id int);
再创建存储过程proc2:
create or replace procedure proc2() as
beginraise notice '--begin to drop table t2,time=%',clock_timestamp();drop table if exists t2;raise notice '--drop table t2,time=%',clock_timestamp();raise notice '--begin to alter table t1 rename to t2,time=%',clock_timestamp(); alter table t1 rename to t2;raise notice '--alter table t1 rename to t2,time=%',clock_timestamp(); raise notice '--do something...,time=%',clock_timestamp(); perform pg_sleep(30);raise notice '--begin to commit,time=%',clock_timestamp();commit;raise notice '-- commit over,time=%',clock_timestamp();raise notice 'job is over,time=%',clock_timestamp();exception when others thenraise notice 'sqlstate=%,sqlerrm=%', sqlstate,sqlerrm;
end;
/
完整的执行结果如下:
postgres=# call proc2();
NOTICE: --begin to drop table t2,time=2021-12-22 17:57:58.572717+08
NOTICE: --drop table t2,time=2021-12-22 17:57:58.573627+08
NOTICE: --begin to alter table t1 rename to t2,time=2021-12-22 17:57:58.57374+08
NOTICE: --alter table t1 rename to t2,time=2021-12-22 17:57:58.57425+08
NOTICE: --do something...,time=2021-12-22 17:57:58.574311+08
NOTICE: --begin to commit,time=2021-12-22 17:58:28.575849+08
NOTICE: -- commit over,time=2021-12-22 17:58:28.774332+08
NOTICE: job is over,time=2021-12-22 17:58:28.774389+08
可以看出,openGauss/MogDB里可以完整执行。
总结
通过两个实验,我们对比测试存储过程中commit与exception的使用。实验一结果一致,实验二结果不一致。
1.通过实验一我们了解可以使用commit语句立刻提交来确保程序块所作的变化对其它客户端可见,并且这是不可撤销的(rollback)。
2.在PostgreSQL里面,我们不能在有exception子句的存储过程使用commit或者rollback语句,openGauss/MogDB里则可以兼容这两种操作。
墨天轮原文链接:https://www.modb.pro/db/220168?sjhy(复制链接至浏览器或点击文末阅读原文查看)
关于作者
彭冲,云和恩墨PG技术顾问,网名“多米爸比”,PG社区认证专家,中国首期PostgreSQL ACE Partner,多年从事基于PostgreSQL数据库的软件研发,擅长于PL/PGSQL业务迁移及优化,Oracle到PostgreSQL的迁移升级,异构数据库整合;作为墨天轮PostgreSQL实践专栏作者,热衷于PostgreSQL实践技术分享,在自己的岗位积极推广PostgreSQL,致力为PG社区多做奉献。
END
推荐阅读:2021数据技术嘉年华视频回放及PPT下载
2021数据技术嘉年华50余个PPT下载、视频回放已上传墨天轮平台,可在“数据和云”公众号回复关键词“2021DTC”获得!
你知道吗?我们的视频号里已经发布了很多精彩的内容,快去看看吧!↓↓↓
点击下图查看更多 ↓
云和恩墨大讲堂 | 一个分享交流的地方
长按,识别二维码,加入万人交流社群
请备注:云和恩墨大讲堂
点个“在看”
你的喜欢会被看到❤
MogDB存储过程事务控制与异常块相关推荐
- SpringMVC与Mybatis集合实现调用存储过程、事务控制
在SSM框架中经常会用到调用数据库中的存储过程.以及事务控制,下面以保存某单据为例,介绍一下: 1.Oracle中存储过程代码如下(主要逻辑将单据编码自动加1,并将该单据编码返回): CREATE O ...
- controller的异常处理以及service层的事务控制___controller层 trycatch不影响service层抛出的异常
controller的异常处理以及service层的事务控制 最近写代码涉及到一些事务,上午终于把代码给理顺了,之前不太清楚在哪里做异常处理,导致代码遍地try-catch,相当难看. 还是基于con ...
- 服务器无法继续该事务 3400000006 错误原因--JAVA调用SQLSERVER存储过程时过程发生异常内部事务未
通过JAVA调用SQLSERVER存储过程时,存储过程内部发生了类型转换异常,在类型转换异常发生之前已经将事务打开了,并且在类型转换那一行没有采用像如下错误处理: if @@error<> ...
- 0046 @Transactional注解的几个参数--事务传播控制--事务隔离级别--异常与回滚
0046 @Transactional注解的几个参数--事务传播控制--事务隔离级别--异常与回滚 参考文章: (1)0046 @Transactional注解的几个参数--事务传播控制--事务隔离级 ...
- @Transactional注解的几个参数--事务传播控制--事务隔离级别--异常与回滚
@Transactianal注解有一些属性,见Spring-Framework-Reference Table17.3 Transactional-settings @Transactional(pr ...
- c# mysql代码中写事务_代码中添加事务控制 VS(数据库存储过程+事务) 保证数据的完整性与一致性...
[c#]代码库代码中使用事务前提:务必保证一个功能(或用例)在同一个打开的数据连接上,放到同一个事务里面操作. 首先是在D层添加一个类为了保存当前操作的这一个连接放到一个事务中执行,并事务执行打开同一 ...
- Spring——DAO层、Spring JDBC、Spring事务控制
目录 一.Spring对持久层技术支持 1.Spring支持的持久层技术 2.Spring JDBC 2.1. JDBCTemplate类 2.2.Spring JDBC CRUD操作 2.3.Spr ...
- java web 转账事务控制
转账事务控制 1.数据准备 CREATE TABLE `account` (`aid` int(11) NOT NULL AUTO_INCREMENT,`uname` varchar(255) DEF ...
- 【spring】spring基于xml的声明式事务控制
结构 domain package com.itheima.domain;import java.io.Serializable;public class Account implements Ser ...
最新文章
- Assembly--及相关内容
- Transformer的潜在竞争对手QRNN论文解读,训练更快的RNN
- python爬虫正则表达式实例-python爬虫学习三:python正则表达式
- 你用过这种奇葩的C#注释吗?如何看待
- 无法在流的结尾之外进行读取_IO流,字节流,字符流
- opendolphin_使用DolphinDB进行机器学习
- 电子商务基础课件(10.25更新)
- 【老王来了】之隔壁路由器坏了,他来了...
- android 保存文件_Android 数据库操作框架LitePal使用介绍(一)
- zabbix系统日志文件监控key
- A joke about regular expression
- 死磕算法!35篇算法设计实例+6本必读书打包送你
- 故障:在 Application Log 中出现 ID57860 的 Backup Exec 错误日志
- 51单片机读引脚和读端口测试总结
- bat篇---windows bat启动exe结尾的可执行程序
- java--String类常用方法大全
- 爬虫_app 2.7 packet capture抓包工具介绍
- matlab动图启动,MATLAB制作动图或视频
- PP视频(PPTV聚力)web接口分析
- 微博android升级7.000,华为 Android 7.0 升级计划曝光:G9 青春版 /Nova 也有份
热门文章
- cass地籍参数设置命令_想成为一名厉害的测绘员?南方Cass教程+插件+课件不可少!...
- 如何使用Behat在Drupal中使用行为驱动的开发
- 最末参与者优化 lpo_优化博客以提高读者参与度的6种方法
- 组件化开发_思维导图
- jquery和javascript屏蔽右键菜单及阻止事件冒泡
- Less的条件表达式Guards
- 关于python字符编码以下选项中描述错误的是_关于import引用,以下选项中描述错误的是...
- php判断手机浏览器,php 获取 手机浏览器的信息 | 学步园
- 电竞高性能主机可以改云服务器吗,无缘主机平台 NBA 2K League电竞联赛将改用高性能PC...
- php之微型博客创建,php之微型博客的创建