这两天看了11g的CONCEPT文档的事务部分,发现自治事务还有一些以前没有注意到的地方,这里简单总结一下。
描述自治事务与主事务与临时表的关系。
小议自治事务(一):http://yangtingkun.itpub.net/post/468/467765
小议自治事务(二):http://yangtingkun.itpub.net/post/468/467840
小议自治事务(三):http://yangtingkun.itpub.net/post/468/467933
小议自治事务(四):http://yangtingkun.itpub.net/post/468/468031
主事务和自治事务在会话级共享上下文,上文给出了一个共享包中变量的例子,这里再描述临时表的情况。
首先看看会话级的临时表:
SQL> CREATE GLOBAL TEMPORARY TABLE T_SESSION_STAT
2 (ID NUMBER, NAME VARCHAR2(100), VALUE NUMBER)
3 ON COMMIT PRESERVE ROWS;
表已创建。
SQL> CREATE OR REPLACE PROCEDURE P_TEST AS
2 BEGIN
3 INSERT INTO T_SESSION_STAT VALUES (1, 'P_TEST', 1);
4 FOR I IN (SELECT ID, NAME FROM T_SESSION_STAT) LOOP
5 DBMS_OUTPUT.PUT_LINE('ID:' || I.ID || ', NAME:' || I.NAME);
6 END LOOP;
7 END;
8 /
过程已创建。
SQL> CREATE OR REPLACE PROCEDURE P_TEST_AUTO AS
2 PRAGMA AUTONOMOUS_TRANSACTION;
3 BEGIN
4 INSERT INTO T_SESSION_STAT VALUES (2, 'P_TEST_AUTO', 1);
5 FOR I IN (SELECT ID, NAME FROM T_SESSION_STAT) LOOP
6 DBMS_OUTPUT.PUT_LINE('ID:' || I.ID || ', NAME:' || I.NAME);
7 END LOOP;
8 COMMIT;
9 END;
10 /
过程已创建。
SQL> SET SERVEROUT ON
SQL> INSERT INTO T_SESSION_STAT VALUES (0, 'SQL', 1);
已创建 1 行。
SQL> EXEC P_TEST
ID:0, NAME:SQL
ID:1, NAME:P_TEST
PL/SQL 过程已成功完成。
SQL> EXEC P_TEST_AUTO
ID:2, NAME:P_TEST_AUTO
PL/SQL 过程已成功完成。
SQL> EXEC P_TEST
ID:0, NAME:SQL
ID:1, NAME:P_TEST
ID:2, NAME:P_TEST_AUTO
ID:1, NAME:P_TEST
PL/SQL 过程已成功完成。
SQL> COMMIT;
提交完成。
SQL> EXEC P_TEST_AUTO
ID:0, NAME:SQL
ID:1, NAME:P_TEST
ID:2, NAME:P_TEST_AUTO
ID:1, NAME:P_TEST
ID:2, NAME:P_TEST_AUTO
PL/SQL 过程已成功完成。
由于自治事务和主事务属于同一个会话,因此会话级临时表和普通表的表现一样,没有太大的区别。自治事务可以看到主事务中已经提交的修改,看不到没有提交的修改。而自治事务调用完成后,比如提交或回滚,所以主事务也可以看到自治事务的修改。
如果把临时表变成ON COMMIT DELETE ROWS:
SQL> TRUNCATE TABLE T_SESSION_STAT;
表被截断。
SQL> DROP TABLE T_SESSION_STAT;
表已删除。
SQL> CREATE GLOBAL TEMPORARY TABLE T_SESSION_STAT
2 (ID NUMBER, NAME VARCHAR2(100), VALUE NUMBER)
3 ON COMMIT DELETE ROWS;
表已创建。
SQL> INSERT INTO T_SESSION_STAT VALUES (0, 'SQL', 1);
已创建 1 行。
SQL> EXEC P_TEST
ID:0, NAME:SQL
ID:1, NAME:P_TEST
PL/SQL 过程已成功完成。
SQL> EXEC P_TEST_AUTO
BEGIN P_TEST_AUTO; END;
*
第 1 行出现错误:
ORA-14450: 试图访问已经在使用的事务处理临时表
ORA-06512: 在 "YANGTK.P_TEST_AUTO", line 4
ORA-06512: 在 line 1
自治事务的调用居然报错了。
SQL> COMMIT;
提交完成。
SQL> EXEC P_TEST_AUTO
ID:2, NAME:P_TEST_AUTO
PL/SQL 过程已成功完成。
SQL> EXEC P_TEST
ID:1, NAME:P_TEST
PL/SQL 过程已成功完成。
SQL> EXEC P_TEST_AUTO
BEGIN P_TEST_AUTO; END;
*
第 1 行出现错误:
ORA-14450: 试图访问已经在使用的事务处理临时表
ORA-06512: 在 "YANGTK.P_TEST_AUTO", line 4
ORA-06512: 在 line 1
主事务对ON COMMIT DELETE ROWS的临时表进行了修改且未提交时,自治事务不能同时修改这个临时表。这一点也是使用自治事务应该注意的,好在临时表和自治事务配合使用的情况并不多见。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/4227/viewspace-418917/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/4227/viewspace-418917/