[20120421] 自治事务(AUTONOMOUS_TRANSACTION) 与临时表.txt

简介: [20120421] 自治事务(AUTONOMOUS_TRANSACTION) 与临时表.txt前一阵遇到一个死锁的问题,存储过程使用了自治事务,测试以下使用临时表的问题。
[20120421] 自治事务(AUTONOMOUS_TRANSACTION) 与临时表.txt

前一阵遇到一个死锁的问题,存储过程使用了自治事务,测试以下使用临时表的问题。

1.测试环境:
SQL> select * from v$version ;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
PL/SQL Release 11.2.0.1.0 - Production
CORE    11.2.0.1.0      Production
TNS for Linux: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production

drop table t purge ;
create global temporary table t (id number,name varchar2(10)) on commit delete rows;
CREATE UNIQUE INDEX I_T_I ON SCOTT.T(ID);

CREATE  PROCEDURE test1( l_id number,l_name varchar2,flag VARCHAR2) AS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
        IF flag = 'INSERT' THEN
                insert into t values(l_id,l_name);
        END IF;
        IF flag = 'UPDATE' THEN
                update t set id=l_id,name=l_name where id=l_id;
        END IF;
        IF flag = 'DELETE' THEN
                delete from t where id=l_id;
        END IF;
        commit;
        dbms_output.put_line (flag);
END;
/


2.测试:
SQL> insert into t values(1,'a');
1 row created.

SQL> update t set name='aaa' where id=1;
1 row updated.

SQL> exec test1(1,'A','UPDATE');
UPDATE
PL/SQL procedure successfully completed.

--可以发现居然没事!
SQL> select * from t;
        ID NAME
---------- ----------
         1 aaa

--实际上根本没有修改操作。做一个delete操作:
SQL> select * from t;
        ID NAME
---------- ----------
         1 aaa

SQL> exec test1(1,'aaa','DELETE');
DELETE

PL/SQL procedure successfully completed.

SQL> select * from t;
        ID NAME
---------- ----------
         1 aaa
--可以发现根本没有删除记录,就像根本没有执行一样!

--再做一个insert操作!

SQL> select * from t;
        ID NAME
---------- ----------
         1 aaa
SQL> exec test1(1,'A','INSERT');
BEGIN test1(1,'A','INSERT'); END;

*
ERROR at line 1:
ORA-14450: attempt to access a transactional temp table already in use
ORA-06512: at "SCOTT.TEST1", line 6
ORA-06512: at line 1


SQL> select * from t;
        ID NAME
---------- ----------
         1 aaa

--我建立的唯一索引在表T,理论将在插入(1,'A')是应该报ora-00001错误,没有出现。

3.删除临时表T,修改属性为preserver看看。

drop table t purge ;
create global temporary table scott.t ( id    number, name  varchar2(10)) on commit preserve rows;
CREATE UNIQUE INDEX I_T_I ON SCOTT.T(ID);

SQL> insert into t values(1,'a');
1 row created.

SQL> update t set name='aaa' where id=1;
1 row updated.

SQL> exec test1(1,'A','UPDATE');
UPDATE
PL/SQL procedure successfully completed.

SQL> select * from t;
        ID NAME
---------- ----------
         1 aaa

--可以发现居然没事!情况同上!

SQL> exec test1(1,'aaa','DELETE');
DELETE

PL/SQL procedure successfully completed.

SQL> select * from t;
        ID NAME
---------- ----------
         1 aaa

--可以发现根本没有删除记录,就像根本没有执行一样!
--再做一个insert操作!
SQL> exec test1(1,'aaa','INSERT');
BEGIN test1(1,'aaa','INSERT'); END;

*
ERROR at line 1:
ORA-00060: deadlock detected while waiting for resource
ORA-06512: at "SCOTT.TEST1", line 6
ORA-06512: at line 1

--出现了死锁!
SQL> select * from t;
        ID NAME
---------- ----------
         1 aaa

--插入另外的数值看看。
SQL> exec test1(2,'aaa','INSERT');
INSERT

PL/SQL procedure successfully completed.

SQL> select * from t;
        ID NAME
---------- ----------
         1 aaa
         2 aaa

总结:实际上了解临时表的特性就很容易理解以上测试!
从以下链接摘录一段:
http://rajeshwaranbtech.blogspot.com/2010/09/transactionlevel-temporary-tables-with.html

        If you are using GLOBAL TEMPORARY tables, one thing you must be aware of is the fact that a  transaction‐level temporary
table cannot be used by more than one transaction, in a single session, at the same time. Temporary tables are managed at the
session‐level, and when they are created in the mode that makes them ?transactional? (on commit, delete rows), they can only
be used by either the parent, or the child transaction, but not both.
另外我的测试在执行如下代码,并不报错!

SQL> drop table t purge ;
Table dropped.
SQL> create global temporary table t (id number,name varchar2(10)) on commit delete rows;
Table created.
SQL> insert into t values(1,'a');
1 row created.

CREATE OR REPLACE PROCEDURE auto_proc2
AS
   PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
   FOR x IN (SELECT *
               FROM t)
   LOOP
      NULL;
   END LOOP;
END;
/

SQL> exec auto_proc2
PL/SQL procedure successfully completed.





目录
相关文章
|
网络协议 网络虚拟化
CentOS8下yum源配置及nmcli命令简单介绍
CentOS8下yum源配置及nmcli命令简单介绍
2088 0
CentOS8下yum源配置及nmcli命令简单介绍
|
安全 Linux 网络安全
Linux环境中安装和使用Paramiko
Linux环境中安装和使用Paramiko
503 12
|
存储 Oracle Unix
关于小机 | 计算机百年趣味史(上)第8篇
小机即小型机(minicomputer),从名字上我们可以知道是体积会较小的机器,不过体积也是针对大机(mainframe)来说是,如果光从绝对体积上讲,那显然又不对。所以,小机是对特定时代一群类似机器的统称。我们来看下小机的关键历史。其历史时间是与大型机并行的。
2916 0
关于小机 | 计算机百年趣味史(上)第8篇
|
12月前
|
SQL 缓存 分布式计算
阿里云连续五年入选Gartner®分析和商业智能平台魔力象限,中国唯一
Gartner® 正式发布《分析与商业智能平台魔力象限》报告(Magic Quadrant™ for Analytics and Business Intelligence Platforms),阿里云成为唯一入围该报告的中国厂商,被评为“挑战者”(Challengers)。这也是阿里云连续五年入选该报告。
|
设计模式 消息中间件 存储
18个并发场景的设计模式详解,有没有你的盲区
这些模式在多线程并发编程中非常有用`。在分布式应用中,并发场景无处不在,理解和掌握这些并发模式的编码技巧,有助于我们在开发中解决很多问题,这要把这些与23种设计模式混淆了,虽然像单例模式是同一个,但这个是考虑并发场景下的应用。内容比较多,V哥建议可以收藏起来,即用好查。拜拜了您誒,晚安。
410 1
18个并发场景的设计模式详解,有没有你的盲区
|
关系型数据库 MySQL 测试技术
压测工具sysbench的使用
压测工具sysbench的使用
1048 0
|
关系型数据库 MySQL 调度
深入理解MySQL InnoDB线程模型
深入理解MySQL InnoDB线程模型
|
数据采集 存储 监控
InfluxDB与Telegraf:数据采集与监控实战
【4月更文挑战第30天】本文介绍了InfluxDB和Telegraf在数据采集与监控中的应用。InfluxDB是高性能的时序数据库,适合高吞吐量和实时查询,而Telegraf是数据采集代理,能收集多种系统指标并发送至InfluxDB。实战部分涉及安装配置两者,通过Telegraf收集数据,然后使用InfluxDB查询分析,配合Grafana实现可视化展示,从而实现有效的监控解决方案。
|
设计模式 中间件 测试技术
系统困境与软件复杂度:为什么我们的系统会如此复杂?
很多人认为做业务开发没有挑战性,但其实正好相反,面向不确定性设计才是最复杂的设计。
2072 110
系统困境与软件复杂度:为什么我们的系统会如此复杂?