发表于: 2008.08.07 22:55
分类: ORACLE
出处: http://yangtingkun.itpub.net/post/468/468405
---------------------------------------------------------------
测试自治事务的时候访问临时表出现了这个错误,简单总结一下。
临时表的ORA-14552错误:http://yangtingkun.itpub.net/post/468/468322
造成这个错误的原因就是一个事务访问了ON COMMIT DELETE ROWS的临时表,且没有提交的情况下,调用了一个自治事务,而自治事务同样访问了这个临时表,且发出了COMMIT语句:
下面通过一个例子来重现这个错误:
SQL> CREATE GLOBAL TEMPORARY TABLE T_TEMP
2 (ID NUMBER)
3 ON COMMIT DELETE ROWS;
表已创建。
SQL> CREATE OR REPLACE PROCEDURE P_AUTO AS
2 PRAGMA AUTONOMOUS_TRANSACTION;
3 BEGIN
4 INSERT INTO T_TEMP VALUES (1);
5 COMMIT;
6 END;
7 /
过程已创建。
SQL> INSERT INTO T_TEMP VALUES (1);
已创建 1 行。
SQL> EXEC P_AUTO;
BEGIN P_AUTO; END;
*第 1 行出现错误:
ORA-14450: 试图访问已经在使用的事务处理临时表
ORA-06512: 在 "YANGTK.P_AUTO", line 4
ORA-06512: 在 line 1
如果主事务进行了提交,则不会报错:
SQL> COMMIT;
提交完成。
SQL> EXEC P_AUTO;
PL/SQL 过程已成功完成。
查询了一下metalink,发现没有直接描述这个现象的文章,其中有两篇文章也是产生了上面的这个错误分别是Doc ID: Note:252091.1和Doc ID: Note:286646.1。
对于前一篇文章,其实和文章开头给出的链接比较相似,这种情况发生在ON COMMIT PRESERVE ROWS临时表。由于用户对临时表进行了修改之后,没有明确的是否锁,导致对临时表添加字段时报错。
SQL> CREATE GLOBAL TEMPORARY TABLE T_TEMP2
2 (ID NUMBER)
3 ON COMMIT PRESERVE ROWS;
表已创建。
SQL> INSERT INTO T_TEMP2 VALUES (1);
已创建 1 行。
SQL> COMMIT;
提交完成。
SQL> ALTER TABLE T_TEMP2 ADD (NAME VARCHAR2(30));
ALTER TABLE T_TEMP2 ADD (NAME VARCHAR2(30))
*第 1 行出现错误:
ORA-14450: 试图访问已经在使用的事务处理临时表
这时需要断开会话或执行TRUNCATE语句:
SQL> TRUNCATE TABLE T_TEMP2;
表被截断。
SQL> ALTER TABLE T_TEMP2 ADD (NAME VARCHAR2(30));
表已更改。
这种情况其实和上一篇文章中分析的一样。
而第二篇文章中给出的描述是,临时表不支持分布事务,所以访问报错。
看来Oracle同样也不支持自治事务和主事务同时访问ON COMMIT DELETE ROWS临时表。如果需要二者同时访问,那么就要确保主事务在调用自治事务之前首先提交:
SQL> INSERT INTO T_TEMP VALUES (1);
已创建 1 行。
SQL> COMMIT;
提交完成。
SQL> EXEC P_AUTO
PL/SQL 过程已成功完成。











