写点什么

【我和 openGauss 的故事】 openGauss 5.0.0 事务相关语法

作者:daydayup
  • 2023-08-07
    北京
  • 本文字数:2875 字

    阅读完需:约 9 分钟

【我和 openGauss 的故事】 openGauss 5.0.0 事务相关语法

秋秋 [openGauss](javascript:void(0);) 2023-08-03 16:49 发表于四川


众所周知, openGauss 是一款开源关系型数据库管理系统,采用木兰宽松许可证 v2 发行,是 PostgreSQL 9.2.4 版本的硬分叉,经历 HUAWEI 多年的孵化,并已历经了两个 LTS 版本。


现在的 openGauss 5.0.0 正是第三个 LTS 版本,发行于 3 月 31 日,版本生命周期为三年。


openGauss 5.0.0 是流行的开源关系型数据库管理系统,它支持事务处理,下面我们来看看。

事务隔离级别

在 openGauss 5.0.0 中,支持 READ COMMITTED (读已提交)和 REPEATABLE READ (可重复读) 两种事务隔离级别。默认隔离级别是 READ COMMITTED (读已提交),保证不会读到脏数据。当事务使用此隔离级别时,SELECT 查询(没有 FOR UPDATE/SHARE 子句)只能看到在查询开始之前提交的数据;它不会看到未提交的数据,也不会看到并发事务在查询执行期间提交的更改。事务可重复读隔离级别,事务只能读到事务开始之前已提交的数据,不能读到未提交的数据以及事务执行期间其它并发事务提交的修改(但是,查询能查看到自身所在事务中先前更新的执行结果,即使先前更新尚未提交)。这个级别和读已提交是不一样的,因为可重复读事务中的查询看到的是事务开始时的快照,不是该事务内部当前查询开始时的快照,就是说,单个事务内部的 select 命令总是查看到同样的数据,查看不到自身事务开始之后其他并发事务修改后提交的数据。使用该级别的应用必须准备好重试事务,因为可能会发生串行化失败。在 openGauss 中,目前功能上不支持 SERIALIZABLE 隔离级别,等价于 REPEATABLE READ。


此外,在 openGauss 5.0.0 中,使用 全局事务管理器(Global Transaction Manager, GTM)来管理事务,GTM 负责全局事务号的分发,事务提交时间戳的分发以及全局事务运行状态的登记。

事务管理命令

在 openGauss 5.0.0 中,可以使用以下命令来启动和提交事务:

使用 BEGIN 语句

openGauss 的语法为:


BEGIN [ WORK | TRANSACTION ] [ { ISOLATION LEVEL { READ COMMITTED | SERIALIZABLE | REPEATABLE READ } | { READ WRITE | READ ONLY } } [, ...] ];
复制代码


演示实例:


begin work isolation level repeatable read read only;
复制代码



使用 START 语句


openGauss 的语法为:


START TRANSACTION [ { ISOLATION LEVEL { READ COMMITTED | SERIALIZABLE | REPEATABLE READ } | { READ WRITE | READ ONLY } } [, ...] ];
复制代码


演示实例:


START TRANSACTION isolation level repeatable read read WRITE;
复制代码



使用 SET 在事务中改变事务隔离级别


openGauss 的语法为:


{ SET [ LOCAL ] TRANSACTION|SET SESSION CHARACTERISTICS AS TRANSACTION } { ISOLATION LEVEL { READ COMMITTED | SERIALIZABLE | REPEATABLE READ } | { READ WRITE | READ ONLY } } [, ...];
复制代码


演示实例:


SET LOCAL TRANSACTION ISOLATION LEVEL REPEATABLE READ;
复制代码



提交事务


openGauss 的语法为:


{ COMMIT | END } [ WORK | TRANSACTION ] ;
复制代码


回滚事务


当事务无法继续进行时,系统执行回滚,取消与该事务相关的所有已完成的数据库操作。


openGauss 的语法为:


ROLLBACK [ WORK | TRANSACTION ];
复制代码


openGauss 事务验证实践

隐式提交案例一则

开启一个会话,尝试在事务显示开启时退出客户端,再次登入后查看数据是否插入成功,答案是否。


`openGauss=# begin;BEGINopenGauss=# insert into t select 2;INSERT 0 1openGauss=# select * from t;id12(2 rows)
$ gsqlgsql ((openGauss 5.0.0 build a07d57c3) compiled at 2023-03-29 03:07:56 commit 0 last mr )Non-SSL connection (SSL connection is recommended when requiring high-security)Type “help” for help.
openGauss=# select * from t;id1(1 row)`
复制代码


说明在事务中退出客户端,当前事务并不会隐式提交。

默认事务隔离级别 RC

openGauss 中默认事务提交级别 RC,下面做一个实验加以验证。


开启两个会话,Session A 和 Session B:


`-- Session A:openGauss=# begin;BEGINopenGauss=# insert into t select 3;INSERT 0 1openGauss=# select * from t;id13(2 rows)
– Session B:openGauss=# begin;BEGINopenGauss=# select * from t;id1(1 row)`
复制代码


当前会话只能看到事务开始之前的 t 表数据。并且,Session B 无法读到未提交的数据,不存在脏读现象。

DDL 可回滚 – create table

在 openGauss 中,显式开启一个事务,然后执行 DDL 语句,那么这个 DDL 语句可以进行回滚,确认语句没有问题后,再进行显式提交。例如,在 Session A 中开启显式事务,并创建表 tr。


`-- Session A:openGauss=# begin;BEGINopenGauss=# create table tr (id int);CREATE TABLEopenGauss=# \dtList of relationsSchema | Name | Type | Owner | Storage--------±-----±------±------±---------------------------------public | t | table | omm | {orientation=row,compression=no}public | tr | table | omm | {orientation=row,compression=no}(2 rows)
– Session B:openGauss=# \dList of relationsSchema | Name | Type | Owner | Storage--------±-----±------±------±---------------------------------public | t | table | omm | {orientation=row,compression=no}(1 row)
– Session A:openGauss=# rollback;ROLLBACKopenGauss=# \dtList of relationsSchema | Name | Type | Owner | Storage--------±-----±------±------±---------------------------------public | t | table | omm | {orientation=row,compression=no}(1 row)
– Session B:openGauss=# \dList of relationsSchema | Name | Type | Owner | Storage--------±-----±------±------±---------------------------------public | t | table | omm | {orientation=row,compression=no}(1 row)`
复制代码

DDL 可回滚 – truncate table

同样地,在 openGauss 中,truncate table 也可以回滚。例如,清空表 t 的数据:


`-- Session A:openGauss=# select * from t;id1(1 row)
openGauss=# begin;BEGINopenGauss=# truncate table t;TRUNCATE TABLEopenGauss=# select * from t;id(0 rows)
– Session B:$ gsqlgsql ((openGauss 5.0.0 build a07d57c3) compiled at 2023-03-29 03:07:56 commit 0 last mr )Non-SSL connection (SSL connection is recommended when requiring high-security)Type “help” for help.
openGauss=# select * from t;id1(1 row)
openGauss=# select * from t;`
复制代码


此时, Session A 中的 truncate 操作已经执行完成,可以看到事务中表中无数据,但是,Session B 再次去查询表 t 的数据时,事务会进入等待状态,直到 Session A 发出 commit/rollback 指令。


`-- Session A:openGauss=# rollback;ROLLBACK
openGauss=# select * from t;id1(1 row)
– Session B:openGauss=# select * from t;id1(1 row)`
复制代码


此外,由于 openGauss 引入了分布式事务,所以对于事务的处理复杂的多。

用户头像

daydayup

关注

还未添加个人签名 2023-07-18 加入

还未添加个人简介

评论

发布
暂无评论
【我和openGauss的故事】 openGauss 5.0.0 事务相关语法_daydayup_InfoQ写作社区