VastbaseG100

基于openGauss内核开发的企业级关系型数据库。

Menu

自治事务

功能描述

自治事务是一种自动管理事务的机制,是指在一个事务中,数据库自动处理并提交内部的嵌套事务,而且无需应用程序显式地管理。

该文档只用于介绍自治事务在Oracle兼容模式下的表现,原Vastbase的自治事务未做删除和修改,详见自治事务

在Oracle兼容模式下,package中支持自治事务,但是不能在package实例中声明,只能在package的函数或过程中声明。

package的自治事务函数或自治事务过程处理与自治事务函数或自治事务过程功能一样。当自治事务函数/过程中访问了package的变量,package的状态是会话级别的,与事务无关,因此主事务和自治事务中package的状态是共享的,即主事务或自治事务修改了package的变量时,该修改对于其主事务或者自治事务是可见的。

注意事项

  • package中支持自治事务特性,仅在数据库兼容模式为Oracle时支持(即数据库实例初始化时指定DBCOMPATIBILITY='A')。

  • 声明为自治事务的函数/存储过程对返回值以及参数有如下限制:

    • 不支持集合作为返回值。

    • 不支持组合类型作为返回类型。

    • 不支持游标类型。

    • 不支持out参数。

  • 支持版本:

    • Vastbase G100 V2.2 Build 15 (Patch No.4)及以上补丁版本。

    • Vastbase G100 V2.2 Build 16 及以上版本。

语法格式

PRAGMA AUTONOMOUS_TRANSACTION;

示例

示例1: 在package中声明自治事务(package中自定义函数为自治事务,函数有入参,自治事务回滚)。

1、创建测试表。

create table tb_1188082 (id int);

2、创建包。

CREATE OR REPLACE PACKAGE pkg_1188082 is
function pkg_1188082_fun1(i int) return int;
function pkg_1188082_fun2(i int) return int;
id1 int:= 1;
end pkg_1188082;
/

3、创建包体,在包体定义两个函数并声明自治事务。

CREATE OR REPLACE PACKAGE BODY pkg_1188082 is
function pkg_1188082_fun1(i int) return int is
res int;
PRAGMA AUTONOMOUS_TRANSACTION; --声明了自主事务,这意味着pkg_1188082_fun1函数内部的SQL操作将在一个独立的事务中执行
begin
insert into tb_1188082 values(id1);
rollback;
insert into tb_1188082 values(i+id1);
commit;
res:=id1;
return res;
end;
function pkg_1188082_fun2(i int) return int is
res int;
PRAGMA AUTONOMOUS_TRANSACTION; ----声明了自主事务
begin
insert into tb_1188082 values(i+id1);
res := i;
return res;
commit;
end;
begin
id1 := 2;
end pkg_1188082;
/

4、调用包函数。

select pkg_1188082.pkg_1188082_fun1(10) from dual;
select * from tb_1188082;
select pkg_1188082.pkg_1188082_fun2(100) from dual;
select * from tb_1188082;

返回结果分别为:

pkg_1188082_fun1
-----------------
              2
(1 row)

 id
----
 12
(1 row)

pkg_1188082_fun2
-----------------
              100
(1 row)

 id
----
 12
102
(2 rows)

5、清理测试数据。

DROP TABLE tb_1188082;
DROP PACKAGE pkg_1188082;

示例2: 自治事务访问了package变量(数组变量)。

1、创建测试表并插入数据。

create table t_1189577 (id int,id1 int,id2 int);
insert into t_1189577 values(1,1,1);
insert into t_1189577 values(2,2,2);
insert into t_1189577 values(3,3,3);

2、创建包pkg_1189577,在包中定义两个类型:array_integer(整数表),array_integer1(以varchar(20)为索引的整数表)。

create or replace package pkg_1189577 as
type array_integer is table of int;
type array_integer1 is table of int index by varchar(20);
end;
/

3、创建包pkg_1189577_1,在包中定义array_integer_1数组变量和名为num3的数字变量。

create or replace package pkg_1189577_1 as
procedure p_1189577;
procedure p_1189577_1(id int);
array_integer_1 pkg_1189577.array_integer := pkg_1189577.array_integer(1,2,3); --声明数组变量
num3 number;
end;
/

4、创建包体,在包体中定义两个过程p_1189577和p_1189577_1,这两个过程都使用了PRAGMA AUTONOMOUS_TRANSACTION,这意味着这些过程内部的任何DML操作(如INSERT、UPDATE或DELETE)都会提交或回滚为单独的事务,而不影响其它事务。

CREATE OR REPLACE PACKAGE BODY pkg_1189577_1 IS
procedure p_1189577
as
PRAGMA AUTONOMOUS_TRANSACTION;
begin
array_integer_1(1) := 1;
select id1 into num3 from t_1189577 where id = array_integer_1(1);
dbms_output.put_line(num3);
array_integer_1(1) :=num3+1;
commit;
end;
procedure p_1189577_1(id int)
as
PRAGMA AUTONOMOUS_TRANSACTION;
begin
p_1189577();
commit;
select id1 into num3 from t_1189577 where id = array_integer_1(1);
dbms_output.put_line(num3);
dbms_output.put_line(array_integer_1(1));
rollback;
dbms_output.put_line(array_integer_1(1));
update t_1189577 set id1 = 22+id1 where id = array_integer_1(1);
commit;
end;
end pkg_1189577_1;
/

5、打开serveroutput参数。(使信息从存储过程传输回应用程序,输出在屏幕上。)

set serveroutput on;

6、调用pkg_1189577_1.p_1189577_1(2)过程,并查询了t_1189577表的结果。

call pkg_1189577_1.p_1189577_1(2);
select * from t_1189577 order by 1,2,3;

返回结果为:

NOTICE:  1
CONTEXT:  SQL statement "CALL pkg_1189577_1.p_1189577()"
PL/pgSQL function public.pkg_1189577_1.p_1189577_1(integer) line 3 at PERFORM
NOTICE:  2
NOTICE:  2
NOTICE:  2
pkg_1189577_1
--------------

(1 row)


 id | id1 | id2
----+-----+-----
  1 |   1 |   1
  2 |  24 |   2
  3 |   3 |   3
(3 rows)

7、对pkg_1189577_1的包体进行更新,修改了p_1189577过程内部的逻辑,将array_integer_1(1)的值更新为num3+2而不是num3+1。

CREATE OR REPLACE PACKAGE BODY pkg_1189577_1 IS
procedure p_1189577
as
PRAGMA AUTONOMOUS_TRANSACTION;
begin
array_integer_1(1) := 1;
select id1 into num3 from t_1189577 where id = array_integer_1(1);
dbms_output.put_line(num3);
array_integer_1(1) :=num3+2;
commit;
end;
procedure p_1189577_1(id int)
as
PRAGMA AUTONOMOUS_TRANSACTION;
begin
p_1189577();
commit;
select id1 into num3 from t_1189577 where id = array_integer_1(1);
dbms_output.put_line(num3);
dbms_output.put_line(array_integer_1(1));
rollback;
dbms_output.put_line(array_integer_1(1));
update t_1189577 set id1 = 22+id1 where id = array_integer_1(1);
commit;
end;
end pkg_1189577_1;
/

8、重新调用包并查询结果。

call pkg_1189577_1.p_1189577_1(2);
select * from t_1189577 order by 1,2,3;

返回结果为:

NOTICE:  1
CONTEXT:  SQL statement "CALL pkg_1189577_1.p_1189577()"
PL/pgSQL function public.pkg_1189577_1.p_1189577_1(integer) line 3 at PERFORM
NOTICE:  3
NOTICE:  3
NOTICE:  3
pkg_1189577_1
--------------

(1 row)


 id | id1 | id2
----+-----+-----
  1 |   1 |   1
  2 |  24 |   2
  3 |  25 |   3
(3 rows)

9、清理测试数据。

DROP TABLE t_1189577;
DROP PACKAGE pkg_1189577;
DROP PACKAGE pkg_1189577_1;