暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

openGauss显式事务和隐式事务

openGauss小助手 2021-10-21
998

显式事务是指,用户在所执行的一条或多条SQL语句的前后,显式添加了开启事务START TRANSACTION语句和提交事务COMMIT语句。

隐式事务是指,用户在所执行的一条或多条SQL语句的前后,没有显式添加开启事务和提交事务的语句。在这种情况下,每一条SQL语句在开始执行时,openGauss内部都会为其开启一个事务,并且在该语句执行完成之后,自动提交该事务。

以一条SELECT语句和一条INSERT语句为例,简要描述显式事务和隐式事务在openGauss集群中的主要执行流程。

显式事务的SQL语句如下(假设表t只包含一个整数类型字段a,且为分布列):

START TRANSACTION;

SELECT * FROM t;

INSERT INTO t(a) VALUES (100);

COMMIT;

1)START TRANSACTION

该SQL语句只在CN上执行,CN显式开启一个事务,并将CN本地事务块状态机从空闲状态置为进行中状态,然后返回客户端,等待下一条SQL命令。

2)SELECT * FROM t

该SQL语句首先在CN上执行,由于openGauss分片采用一致性哈希算法,因此对于不带分布列上谓词条件的查询语句,CN需要将该SQL语句发送到所有DN实例上执行。对于每一个分片对应的DN实例,由于采用了显式事务,CN会先发送一条START TRANSACTION命令给该DN,让该DN显式开启事务(DN上的事务块状态机从空闲状态变为进行中状态),然后CN将SELECT语句发送给该DN。此后,CN在收到所有DN的查询结果之后,返回客户端,等待下一条SQL命令。

3)INSERT INTO t(a) VALUES (100)

该SQL语句首先在CN上执行,由于a为表t的分布列,因此CN可以根据被插入记录中a的具体取值,来决定应该由哪个数据分片对应的DN实例来执行实际的插入操作(这里假设该分片为DN1)。由于采用了显式事务,CN先发送一条START TRANSACTION命令给DN1,由于经过第(2)步DN1的事务块状态机已经处于进行中状态,因此对于该语句DN1并不会执行什么实际的操作,然后,CN将具体的INSERT语句发送给DN1,并等待DN1执行插入成功之后,返回客户端,等待下一条SQL命令。

4)COMMIT

该SQL语句首先在CN上执行,CN进入提交事务阶段后,将COMMIT语句发送给所有参与第(2)步和第(3)步的DN,让这些DN结束该事务,并将DN本地的事务块状态机从进行中状态置为空闲状态。CN在收到所有DN的事务提交结果之后,再将CN本地的事务块状态机从进行中状态置为空闲状态。然后,CN返回客户端,该事务执行完成。

上述操作的隐式事务语句如下(假设表t只包含一个整数类型字段a,且为分布列):

SELECT * FROM t;

INSERT INTO t(a) VALUES (1);

1)SELECT * FROM t

该SQL语句首先在CN上执行,CN隐式开启一个事务,将CN本地的事务块状态机从空闲状态置为开启状态(注意不同于显式事务中的进行中状态)。然后,CN需要将该语句发送到所有DN实例上执行。对于每一个分片对应的DN实例,由于采用了隐式事务且该语句为只读查询,CN直接将SELECT语句发送给该DN。

DN收到该SELECT语句之后,亦采用隐式事务:第一步,隐式开启事务,将DN本地的事务块状态机从空闲状态置为开启状态;第二步,执行该查询语句,将查询结果返回给CN;第三步,隐式提交事务,将DN本地的事务块状态机从开启状态置为空闲状态。

CN在收到所有DN的查询结果之后,返回客户端,并隐式提交事务,将CN本地的事务块状态机从开启状态置为空闲状态。

2)INSERT INTO t(a) VALUES (1)

该SQL语句首先在CN上执行,CN隐式开启一个事务,将CN本地的事务块状态机从空闲状态置为开启状态。然后,CN需要将该INSERT语句发送到目的分片的DN实例上执行(这里假设该分片为DN1)。

虽然该语句采用了隐式事务,但是由于该语句为写操作,因此在DN1上会采取显式事务:CN会先发送一条START TRANSACTION命令给DN1,让DN1显式开启事务(DN1上的事务块状态机从空闲状态变为进行中状态),然后CN将INSERT语句发送给DN1,DN1执行完成后,返回执行结果给CN。

CN收到执行结果之后,进入提交事务阶段。先发送COMMIT语句到DN1。DN1收到COMMIT语句后,进行显式提交,将DN1本地的事务块状态机从进行中状态置为空闲状态。CN在收到DN1的事务提交结果之后,本地再进行隐式提交事务,将CN本地的事务块状态机从开启状态置为空闲状态,返回客户端,该事务执行完成。

综上,对于CN来说,使用显式事务还是隐式事务,完全取决于用户输入的SQL语句;对于DN来说,只有当SQL为隐式只读事务时,才会使用隐式事务,当SQL为显式事务或者隐式写事务时,都会使用显式事务。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论