自治事務(wù)是由調(diào)用程序啟動的獨(dú)立事務(wù)。自治事務(wù)中SQL命令的提交或回滾對調(diào)用程序的任何事務(wù)中的提交或回滾都沒有影響。調(diào)用程序中的提交或回滾對自治事務(wù)中SQL命令的提交或回滾也沒有影響。
通過在SPL塊的聲明部分中指定以下指令,可將SPL程序聲明為自治事務(wù):
PRAGMA AUTONOMOUS_TRANSACTION;
以下SPL程序可包含 PRAGMA AUTONOMOUS_TRANSACTION:
- 獨(dú)立的存儲過程和函數(shù)。
- 匿名塊。
- 包中聲明為子程序的存儲過程和函數(shù)以及其他調(diào)用存儲過程、函數(shù)和匿名塊。
- 觸發(fā)器。
- 對象類型方法。
下面是與自治事務(wù)有關(guān)的問題和限制:
- 每個自治事務(wù)只要在進(jìn)行中,就會消耗一個連接槽。在某些情況下,這可能意味著應(yīng)增大postgresql.conf文件中的max_connections參數(shù)。
- 在大多數(shù)方面,自治事務(wù)的行為就像是一個完全獨(dú)立的會話,但GUC(即通過SET建立的設(shè)置)是一個有意制造的例外。自治事務(wù)吸收周圍的值,并可以將它們提交的值傳播到外部事務(wù)。
- 自治事務(wù)可以嵌套,但在單個會話中自治事務(wù)的嵌套級別限制為16級。
- 自治事務(wù)中不支持并行查詢。
- 自治事務(wù)的PolarDB PostgreSQL版(兼容Oracle)實(shí)現(xiàn)與Oracle數(shù)據(jù)庫不完全兼容,因?yàn)槿绻鸖PL塊末尾有未提交的事務(wù),則PolarDB PostgreSQL版(兼容Oracle)自治事務(wù)不會產(chǎn)生錯誤。
以下一組示例闡釋了自治事務(wù)的用法。第一組場景顯示了沒有自治事務(wù)時的默認(rèn)行為。
在每個場景之前,dept表重置為以下初始值:
SELECT * FROM dept;
deptno | dname | loc
--------+------------+----------
10 | ACCOUNTING | NEW YORK
20 | RESEARCH | DALLAS
30 | SALES | CHICAGO
40 | OPERATIONS | BOSTON
(4 rows)
場景
- 場景1a:沒有自治事務(wù),只有最終COMMIT
第一組場景顯示了如何插入三行,首先就從事務(wù)的初始BEGIN命令之后開始插入第一行,然后從起始事務(wù)的匿名塊插入第二行,最后從匿名塊內(nèi)執(zhí)行的存儲過程插入第三行。
該存儲過程如下:
CREATE OR REPLACE PROCEDURE insert_dept_70 IS BEGIN INSERT INTO dept VALUES (70,'MARKETING','LOS ANGELES'); END;
PSQL會話如下:
BEGIN; INSERT INTO dept VALUES (50,'HR','DENVER'); BEGIN INSERT INTO dept VALUES (60,'FINANCE','CHICAGO'); insert_dept_70; END; COMMIT;
在最后提交后,將插入所有三行:
SELECT * FROM dept ORDER BY 1; deptno | dname | loc --------+------------+------------- 10 | ACCOUNTING | NEW YORK 20 | RESEARCH | DALLAS 30 | SALES | CHICAGO 40 | OPERATIONS | BOSTON 50 | HR | DENVER 60 | FINANCE | CHICAGO 70 | MARKETING | LOS ANGELES (7 rows)
- 場景1b:沒有自治事務(wù),但有最終ROLLBACK
下一個場景顯示,所有插入之后的最后一個ROLLBACK命令將導(dǎo)致所有三個插入的回滾:
BEGIN; INSERT INTO dept VALUES (50,'HR','DENVER'); BEGIN INSERT INTO dept VALUES (60,'FINANCE','CHICAGO'); insert_dept_70; END; ROLLBACK; SELECT * FROM dept ORDER BY 1; deptno | dname | loc --------+------------+---------- 10 | ACCOUNTING | NEW YORK 20 | RESEARCH | DALLAS 30 | SALES | CHICAGO 40 | OPERATIONS | BOSTON (4 rows)
- 場景1c:沒有自治事務(wù),但有匿名塊ROLLBACK
匿名塊結(jié)尾給出的ROLLBACK命令也消除了所有以前的三個插入:
BEGIN; INSERT INTO dept VALUES (50,'HR','DENVER'); BEGIN INSERT INTO dept VALUES (60,'FINANCE','CHICAGO'); insert_dept_70; ROLLBACK; END; COMMIT; SELECT * FROM dept ORDER BY 1; deptno | dname | loc --------+------------+---------- 10 | ACCOUNTING | NEW YORK 20 | RESEARCH | DALLAS 30 | SALES | CHICAGO 40 | OPERATIONS | BOSTON (4 rows)
下一組場景顯示了在不同位置使用PRAGMA AUTONOMOUS_TRANSACTION自治事務(wù)的效果。
- 場景2a:帶有COMMIT的匿名塊的自治事務(wù)
存儲過程保持最初創(chuàng)建的樣子:
CREATE OR REPLACE PROCEDURE insert_dept_70 IS BEGIN INSERT INTO dept VALUES (70,'MARKETING','LOS ANGELES'); END;
現(xiàn)在,PRAGMA AUTONOMOUS_TRANSACTION通過匿名塊給出,并且匿名塊末尾給出COMMIT命令。
BEGIN; INSERT INTO dept VALUES (50,'HR','DENVER'); DECLARE PRAGMA AUTONOMOUS_TRANSACTION; BEGIN INSERT INTO dept VALUES (60,'FINANCE','CHICAGO'); insert_dept_70; COMMIT; END; ROLLBACK;
在事務(wù)結(jié)束時執(zhí)行ROLLBACK后,只丟棄了事務(wù)開始時的第一行插入。帶有PRAGMA AUTONOMOUS_TRANSACTION的匿名塊中的另兩行插入已獨(dú)立提交。
SELECT * FROM dept ORDER BY 1; deptno | dname | loc --------+------------+------------- 10 | ACCOUNTING | NEW YORK 20 | RESEARCH | DALLAS 30 | SALES | CHICAGO 40 | OPERATIONS | BOSTON 60 | FINANCE | CHICAGO 70 | MARKETING | LOS ANGELES (6 rows)
- 場景2b:帶有COMMIT的自治事務(wù)匿名塊包含帶有ROLLBACK的存儲過程,而不是自治事務(wù)過程
現(xiàn)在,存儲過程在末尾具有ROLLBACK命令。但是,您會看到PRAGMA ANONYMOUS_TRANSACTION未包含在此存儲過程中。
CREATE OR REPLACE PROCEDURE insert_dept_70 IS BEGIN INSERT INTO dept VALUES (70,'MARKETING','LOS ANGELES'); ROLLBACK; END;
現(xiàn)在,該存儲過程中的回滾會在匿名塊中的最終COMMIT命令之前刪除匿名塊中插入的兩行(deptno 60和70)。
BEGIN; INSERT INTO dept VALUES (50,'HR','DENVER'); DECLARE PRAGMA AUTONOMOUS_TRANSACTION; BEGIN INSERT INTO dept VALUES (60,'FINANCE','CHICAGO'); insert_dept_70; COMMIT; END; COMMIT;
在事務(wù)結(jié)束時進(jìn)行最終提交之后,插入的唯一一行是事務(wù)開始時插入的第一行。由于匿名塊是自治事務(wù),因此封閉存儲過程中的回滾對執(zhí)行匿名塊之前發(fā)生的插入沒有影響。
SELECT * FROM dept ORDER by 1; deptno | dname | loc --------+------------+---------- 10 | ACCOUNTING | NEW YORK 20 | RESEARCH | DALLAS 30 | SALES | CHICAGO 40 | OPERATIONS | BOSTON 50 | HR | DENVER (5 rows)
- 場景2c :帶有COMMIT的自治事務(wù)匿名塊包含帶ROLLBACK的存儲過程,該過程也是自治事務(wù)過程
現(xiàn)在,在末尾具有ROLLBACK命令的存儲過程也包含PRAGMA ANONYMOUS_TRANSACTION。這將隔離該存儲過程中ROLLBACK命令的效果。
CREATE OR REPLACE PROCEDURE insert_dept_70 IS PRAGMA AUTONOMOUS_TRANSACTION; BEGIN INSERT INTO dept VALUES (70,'MARKETING','LOS ANGELES'); ROLLBACK; END;
現(xiàn)在,該存儲過程中的回滾會刪除由該過程插入的行,而不是在匿名塊中插入的其他行。
BEGIN; INSERT INTO dept VALUES (50,'HR','DENVER'); DECLARE PRAGMA AUTONOMOUS_TRANSACTION; BEGIN INSERT INTO dept VALUES (60,'FINANCE','CHICAGO'); insert_dept_70; COMMIT; END; COMMIT;
在事務(wù)結(jié)束時進(jìn)行最終提交后,插入的行是從事務(wù)開始時插入的第一行,以及在匿名塊開始時插入的行。回滾的唯一插入是該存儲過程中的插入。
SELECT * FROM dept ORDER by 1; deptno | dname | loc --------+------------+---------- 10 | ACCOUNTING | NEW YORK 20 | RESEARCH | DALLAS 30 | SALES | CHICAGO 40 | OPERATIONS | BOSTON 50 | HR | DENVER 60 | FINANCE | CHICAGO (6 rows)
現(xiàn)在,以下各節(jié)顯示了一系列其他SPL程序類型中的PRAGMA AUTONOMOUS_TRANSACTION的示例。
自治事務(wù)觸發(fā)器
以下示例顯示了使用PRAGMA AUTONOMOUS_TRANSACTION聲明觸發(fā)器的效果。
下表是為了記錄對emp表的更改而創(chuàng)建的:
CREATE TABLE empauditlog (
audit_date DATE,
audit_user VARCHAR2(20),
audit_desc VARCHAR2(20)
);
附加到emp表并將這些更改插入empauditlog表的觸發(fā)器如下:您會看到,在聲明部分中包含了PRAGMA AUTONOMOUS_TRANSACTION。
CREATE OR REPLACE TRIGGER emp_audit_trig
AFTER INSERT OR UPDATE OR DELETE ON emp
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
v_action VARCHAR2(20);
BEGIN
IF INSERTING THEN
v_action := 'Added employee(s)';
ELSIF UPDATING THEN
v_action := 'Updated employee(s)';
ELSIF DELETING THEN
v_action := 'Deleted employee(s)';
END IF;
INSERT INTO empauditlog VALUES (SYSDATE, USER,
v_action);
END;
在BEGIN命令啟動的事務(wù)中執(zhí)行了以下兩個插入到emp表的操作。
BEGIN;
INSERT INTO emp VALUES (9001,'SMITH','ANALYST',7782,SYSDATE,NULL,NULL,10);
INSERT INTO emp VALUES (9002,'JONES','CLERK',7782,SYSDATE,NULL,NULL,10);
下面顯示了emp表中的兩個新行以及empauditlog表中的兩個條目:
SELECT * FROM emp WHERE empno > 9000;
empno | ename | job | mgr | hiredate | sal | comm | deptno
-------+-------+---------+------+--------------------+-----+------+--------
9001 | SMITH | ANALYST | 7782 | 23-AUG-18 07:12:27 | | | 10
9002 | JONES | CLERK | 7782 | 23-AUG-18 07:12:27 | | | 10
(2 rows)
SELECT TO_CHAR(AUDIT_DATE,'DD-MON-YY HH24:MI:SS') AS "audit date",
audit_user, audit_desc FROM empauditlog ORDER BY 1 ASC;
audit date | audit_user | audit_desc
--------------------+--------------+-------------------
23-AUG-18 07:12:27 | polardb | Added employee(s)
23-AUG-18 07:12:27 | polardb | Added employee(s)
(2 rows)
但隨后在此會話期間給出了ROLLBACK命令。emp表不再包含這兩行,而empauditlog表仍包含其兩個條目,這是因?yàn)橛|發(fā)器隱式執(zhí)行了提交,并且PRAGMA AUTONOMOUS_TRANSACTION提交這些更改的操作獨(dú)立于調(diào)用事務(wù)中給出的回滾。
ROLLBACK;
SELECT * FROM emp WHERE empno > 9000;
empno | ename | job | mgr | hiredate | sal | comm | deptno
-------+-------+-----+-----+----------+-----+------+--------
(0 rows)
SELECT TO_CHAR(AUDIT_DATE,'DD-MON-YY HH24:MI:SS') AS "audit date",
audit_user, audit_desc FROM empauditlog ORDER BY 1 ASC;
audit date | audit_user | audit_desc
--------------------+--------------+-------------------
23-AUG-18 07:12:27 | polardb | Added employee(s)
23-AUG-18 07:12:27 | polardb | Added employee(s)
(2 rows)
自治事務(wù)對象類型方法
以下示例顯示了使用PRAGMAAUTONOMOUS_TRANSACTION聲明對象方法的效果。
將創(chuàng)建以下對象類型和對象類型主體。對象類型主體中的成員存儲過程包含聲明部分中的PRAGMA AUTONOMOUS_TRANSACTION以及位于存儲過程結(jié)尾的COMMIT。
CREATE OR REPLACE TYPE insert_dept_typ AS OBJECT (
deptno NUMBER(2),
dname VARCHAR2(14),
loc VARCHAR2(13),
MEMBER PROCEDURE insert_dept
);
CREATE OR REPLACE TYPE BODY insert_dept_typ AS
MEMBER PROCEDURE insert_dept
IS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
INSERT INTO dept VALUES (SELF.deptno,SELF.dname,SELF.loc);
COMMIT;
END;
END;
在以下匿名塊中,將執(zhí)行一個插入到dept表的操作,然后調(diào)用對象的insert_dept方法,最后在匿名塊中執(zhí)行ROLLBACK命令。
BEGIN;
DECLARE
v_dept INSERT_DEPT_TYP :=
insert_dept_typ(60,'FINANCE','CHICAGO');
BEGIN
INSERT INTO dept VALUES (50,'HR','DENVER');
v_dept.insert_dept;
ROLLBACK;
END;
由于insert_dept已聲明為自治事務(wù),因此其插入的部門編號60仍位于表中,但回滾刪除了插入的部門50。
SELECT * FROM dept ORDER BY 1;
deptno | dname | loc
--------+------------+----------
10 | ACCOUNTING | NEW YORK
20 | RESEARCH | DALLAS
30 | SALES | CHICAGO
40 | OPERATIONS | BOSTON
60 | FINANCE | CHICAGO
(5 rows)