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

老老老JR老北
发布于 2023-9-8 14:52
浏览
0收藏

众所周知, 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;

【我和openGauss的故事】 openGauss 5.0.0 事务相关语法-鸿蒙开发者社区

使用 START 语句

openGauss 的语法为:

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

演示实例:

START TRANSACTION isolation level repeatable read read WRITE;

【我和openGauss的故事】 openGauss 5.0.0 事务相关语法-鸿蒙开发者社区

使用 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的故事】 openGauss 5.0.0 事务相关语法-鸿蒙开发者社区

提交事务

openGauss 的语法为:

{ COMMIT | END } [ WORK | TRANSACTION ] ;

回滚事务

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

openGauss 的语法为:

ROLLBACK [ WORK | TRANSACTION ];

openGauss 事务验证实践

隐式提交案例一则

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

`openGauss=# begin;
BEGIN
openGauss=# insert into t select 2;
INSERT 0 1
openGauss=# select * from t;
id
1
2
(2 rows)

$ gsql
gsql ((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;
id
1
(1 row)`

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

默认事务隔离级别 RC

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

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

`-- Session A:
openGauss=# begin;
BEGIN
openGauss=# insert into t select 3;
INSERT 0 1
openGauss=# select * from t;
id
1
3
(2 rows)

– Session B:
openGauss=# begin;
BEGIN
openGauss=# select * from t;
id
1
(1 row)`

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

DDL 可回滚 – create table

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

`-- Session A:
openGauss=# begin;
BEGIN
openGauss=# create table tr (id int);
CREATE TABLE
openGauss=# \dt
List of relations
Schema | 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=# \d
List of relations
Schema | Name | Type | Owner | Storage
--------±-----±------±------±---------------------------------
public | t | table | omm | {orientation=row,compression=no}
(1 row)

– Session A:
openGauss=# rollback;
ROLLBACK
openGauss=# \dt
List of relations
Schema | Name | Type | Owner | Storage
--------±-----±------±------±---------------------------------
public | t | table | omm | {orientation=row,compression=no}
(1 row)

– Session B:
openGauss=# \d
List of relations
Schema | 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;
id
1
(1 row)

openGauss=# begin;
BEGIN
openGauss=# truncate table t;
TRUNCATE TABLE
openGauss=# select * from t;
id
(0 rows)

– Session B:
$ gsql
gsql ((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;
id
1
(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;
id
1
(1 row)

– Session B:
openGauss=# select * from t;
id
1
(1 row)`

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

The End

彩蛋,这里并没有提及 openGauss 的 MOT 特性,对此特性相关事务处理的内容将另行成文。





文章转载自公众号:openGauss

分类
标签
已于2023-9-8 14:52:39修改
收藏
回复
举报
回复
    相关推荐