`
sangei
  • 浏览: 335771 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

自治事务

阅读更多

自治事务(autonomous transaction)允许你创建一个“事务中的事务),它能独立于其父事务提交
或回滚。利用自治事务,可以挂起当前执行的事务,开始一个新事务,完成一些工作,然后提交或回滚,
所有这些都不影响当前执行事务的状态。自治事务提供了一种用PL/SQL 控制事务的新方法,可以用于:
顶层匿名块;
本地(过程中的过程)、独立或打包的函数和过程;
对象类型的方法;
数据库触发器。

通过例子来说明。

创建一个简单的表来保存消息:create table t ( msg varchar2(25) );

接下来创建两个过程,每个过程只是将其名字插入到消息表中,然后提交。不过,其中一个过程是正
常的过程,另一个编写为自治事务。我们将使用这些对象来显示在各种情况下哪些工作会在数据库中持久
保留(被提交)。
首先是AUTONOMOUS_INSERT 过程:

create or replace procedure Autonomous_Insert as
pragma autonomous_transaction;
begin
insert into t values ('Autonomous Insert');
commit;
end;

使用pragma AUTONOMOUS_TRANSACTION。这个指令告诉数据库:执行这个过程时要作为一
个新的自治事务来执行,而且独立于其父事务。
注意: pragma 是一个编译器指令,这是一种编辑器执行某种编译选项的方法。还有其他一些pragma。

以下是“正常”的NONAUTONOMOUS_INSERT 过程:

create or replace procedure NonAutonomous_Insert as
begin
insert into t values ('NonAutonomous Insert');
commit;
end;

下面来观察PL/SQL 代码匿名块中非自治(nonautonomous)事务的行为:

begin
insert into t values ('Anonymous Block');
NonAutonomous_Insert;
rollback;
end;

select * from t;
MSG
-------------------------
Anonymous Block
NonAutonomous Insert

可以看到,匿名块执行的工作(INSERT)由NONAUTONOMOUNS_INSERT 过程提交。两个数据行都已提交,
所以ROLLBACK 命令没有什么可以回滚。把这个过程与自治事务过程的行为加以比较:

delete from t; commit;

begin
insert into t values ( 'Anonymous Block' );
Autonomous_Insert;
rollback;
end;

select * from t;
MSG
-------------------------
Autonomous Insert

在此,只有自治事务中完成并已提交的工作会持久保留。匿名块中完成的INSERT 由第4 行的回滚语
句回滚。自治事务过程的COMMIT 对匿名块中开始的父事务没有影响。

如果在一个“正常”的过程中COMMIT,它不仅会持久保留自己的工作,也会使该会话中
未完成的工作成为永久性的。不过,如果在一个自治事务过程中完成COMMIT,只会让这个过程本身的工作
成为永久性的。

下面是一个小例子。先在表上放一个自治事务触发器,它能捕获一个审计跟踪记录,详细地指出谁
试图更新表,这个人什么时候想更新表,另外还会提供一个描述性消息指出这个人想要修改什么数据。这
个触发器的基本逻辑是:对于不向你直接或间接报告的员工,要防止更新这些员工记录的任何企图。
首先,从SCOTT 模式建立EMP 表的一个副本,以此作为本例使用的表:

create table emp
as
select * from scott.emp;

要创建一个AUDIT_TAB 表,在这个表中存储审计信息。注意,我们使用了列的DEFAULT 属性,从而
默认具有当前登录的用户名以及登记审计跟踪信息的当前日期/时间:

create table audit_tab(username varchar2(30) default user, timestamp date default sysdate, msg varchar2(4000));

创建一个EMP_AUDIT 触发器对EMP 表上的UPDATE 活动进行审计:

create or replace trigger EMP_AUDIT
before update on emp
for each row
declare
pragma autonomous_transaction;
l_cnt number;
begin

select count(*)
into l_cnt
from dual
where EXISTS
(select null
from emp
where empno = :new.empno
start with mgr = (select empno from emp where ename = USER)
connect by prior empno = mgr);
if (l_cnt = 0) then
insert into audit_tab
(msg)
values
('Attempt to update ' || :new.empno);
commit;
raise_application_error(-20001, 'Access Denied');
end if;
end;

注意,这里使用了CONNECT BY 查询。这会根据当前用户分析整个(员工)层次结构。它会验证我们
试图更新的记录是某个下属员工的记录,即这个人会在某个层次上向我们报告。
关于这个触发器的要点,主要如下:
PRAGMA AUTONOMOUS_TRANSACTION 应用于触发器定义。整个触发器是一个“自治事务”,因
此它独立于父事务(即企图完成更新的事务)。
触发器在查询中从它保护的表(EMP 表) 中具体读取。如果这不是一个自治事务,它本身
在运行时就会导致一个变异表错误。自治事务使我们绕开了这个问题,它允许我们读取表,但
是也带来了一个缺点, 我们无法看到自己对表做的修改。在这种情况下需要特别小心,这个逻
辑必须仔细审查。如果我们完成的事务是对员工层次结构本身的一个更新会怎么样?我们不会
在触发器中看到这些修改,在评估触发器的正确性时也要把这考虑在内。
触发器提交。这在以前不可能的,触发器以前从来不能提交工作。这个触发器并不是提交
父事务的工作(实际触发器触发的工作,即更新员工记录),而只是提交了触发器所完成的工作
(审计记录)。
在此,我们建立了EMP 表,其中一个妥善的层次结构(EMPNO-MGR 递归关系)。另外还有一个AUDIT_TAB
表,要在其中记录修改信息的失败企图。我们的触发器可以保证这样一个规则:只有我们的经理或经理的
经理(依此类推)可以修改我们的记录。

update emp set sal = sal*10;
update emp set sal = sal*10
*
ERROR at line 1:
ORA-20001: Access Denied
ORA-06512: at "OPS$TKYTE.EMP_AUDIT", line 21
ORA-04088: error during execution of trigger 'OPS$TKYTE.EMP_AUDIT'

select * from audit_tab;
USERNAME TIMESTAMP MSG
--------- --------- ----------------------------------------
OPS$TKYTE 27-APR-05 Attempt to update 7369

触发器发现了情况,能防止UPDATE 发生,而与此同时,会为这个企图创建一个永久记录(注意它在
AUDIT_TAB 表的CREATE TABLE 语句上如何使用DEFAULT 关键字来自动插入USER 和SYSDATE 值)。接下来,
假设我们作为一个用户登录,想实际完成一个UPDATE,并做一些尝试:

update ops$tkyte.emp set sal = sal*1.05 where ename = 'ADAMS';
1 row updated.update ops$tkyte.emp set sal = sal*1.05 where ename = 'SCOTT';
update ops$tkyte.emp set sal = sal*1.05 where ename = 'SCOTT'
*
ERROR at line 1:
ORA-20001: Access Denied
ORA-06512: at "OPS$TKYTE.EMP_AUDIT", line 21
ORA-04088: error during execution of trigger 'OPS$TKYTE.EMP_AUDIT'

在演示表EMP 的默认安装中,员工ADAMS 是SCOTT 的下属,所以第一个UPDATE 成功。再看第二个
UPDATE,SCOTT 试图给自己加薪,但是由于SCOTT 不向SCOTT 报告(SCOTT 不是自己的下属),所以这个更
新失败了。再登录回到包括AUDIT_TAB 表的模式,可以看到以下结果:

select * from audit_tab;
USERNAME TIMESTAMP MSG
--------- --------- -------------------------------------
---
OPS$TKYTE 27-APR-05 Attempt to update 7369
SCOTT 27-APR-05 Attempt to update 7788

分享到:
评论

相关推荐

    Oracle自治事务的介绍(Autonomous_Transactions)

    Oracle自治事务的介绍(Autonomous_Transactions) Oracle自治事务是一种特殊的数据库事务机制,允许在调用事务的上下文中执行独立的事务。这种机制使用PRAGMA_AUTONOMOUS_TRANSACTION语句来定义自治事务。自治事务...

    事务与锁定的问题 自治事务

    ### 事务与锁定的问题:自治事务详解 #### 一、事务与锁定的基础 在数据库管理中,事务(Transaction)和锁定(Locking)是保证数据完整性和一致性的重要机制。事务被视为一系列操作的集合,这些操作要么全部成功...

    Oracle中怎样用自治事务保存日志表

    自治事务是与主事务相分离的,所以它不能检测到被修改过的行的当前状态。这就好像在主事务提交之前,它们一直处于单独的会话里,对自治事务来说,它们是不可用的。然而,反过来情况就不同了:主事务能够检测到已经...

    oracle自治事务(Trigger)

    ### Oracle自治事务(Trigger)详解 #### 一、概述 Oracle数据库中的触发器是一种存储过程,它被设计为当特定事件发生时自动执行。这些事件包括数据修改操作,如INSERT、UPDATE或DELETE等。触发器可以确保数据的...

    Oracle数据完整性嵌套事务调用分析研究

    在上面的示例中,我们使用 PRAGMA AUTONOMOUS_TRANSACTION 语句来声明自治事务,然后调用 Func_GenerateCode 函数来生成单据编号,并将其保存到数据库中。这样即使保存操作失败,自治事务也可以确保数据的一致性。 ...

    SQLServer存储过程中事务的使用方法

    在SQL Server中,事务是确保数据一致性的重要机制,特别是在存储过程中。存储过程是一组预编译的SQL语句,可以在数据库中被多次调用,提高了效率并降低了网络流量。本篇将详细介绍如何在SQL Server存储过程中使用...

    PLSQL最佳实践

    - 自治事务是一种特殊的事务处理方式,它可以独立于外部事务运行。 - 示例:`BEGIN DBMS_AUTOTASK_ADMINISTRATOR.SET_ATTRIBUTE('my_task', 'enabled', TRUE); COMMIT; EXCEPTION WHEN OTHERS THEN DBMS_AUTOTASK_...

    spring-tx事务管理实例

    在Spring框架中,`spring-tx`模块是用于提供事务管理功能的核心组件。Spring事务管理是企业级Java应用中不可或缺的一部分,它确保了数据的一致性和完整性,尤其是在多线程和分布式环境中。本实例将深入探讨Spring...

    ORACLE-事务ORACLE-TRANSACTION-信息管理与信息系统本科毕业设计.doc

    自治事务可以在事务中执行一些特殊的操作,如日志记录和错误处理。 ORACLE 事务的优点 ORACLE 事务管理提供了以下优点: 1. 保证数据库的一致性和完整性。 2. 提高数据库的可靠性和稳定性。 3. 支持分布式事务和...

    oracle-事务oracle-transaction信息管理与信息系统学士学位论文.doc

    自治事务是指在分布式事务中,每个事务都可以独立地提交或回滚。自治事务可以提高系统的可扩展性和可靠性。 本论文对 Oracle 中的事务管理进行了详细的讨论,涵盖了事务的定义、特征、控制语句、原子性、一致性、...

    oracle触发器调用存储过程

    自治事务必须遵循以下规则:如果要被定义为自治事务的程序是匿名的,则它必须是一个最外层的程序块。如果不是匿名的,则它必须是函数或者过程,或者是包含在一个中。在一个包中,只有其中的函数或过程能够定义成自治...

    oracle-事务oracle-transaction信息管理与信息系统.doc

    自治事务是指在事务中执行的独立操作,它可以在事务中执行,或者在事务外执行。自治事务可以帮助提高系统的并发性和可扩展性。 Oracle 的事务管理机制可以保证数据库的一致性和完整性,提供了原子性、一致性、隔离...

    oracle_专家高级编程 中文 第八章

    - **自治事务的作用**:自治事务主要用于审计和日志记录,因为它可以确保即使在外部事务失败的情况下,关键的日志信息也能被正确记录。 #### 八、小结 通过本章的学习,我们深入理解了Oracle数据库中事务的基本...

    oracle开发常用知识

    #### 自治事务(Autonomous Transactions) 自治事务是一种特殊的Oracle事务处理机制,主要用于解决在存储过程或函数内部进行独立于外部事务控制的数据库操作需求。自治事务的特点在于它们不会受到外部事务的影响,...

    基于PL_SQL语言实现数据验证平台中的事务处理.pdf

    此外,PL/SQL还支持自治事务,即在一个块结构内部独立于主事务的事务控制,这为处理复杂逻辑提供了灵活性。 通过这种方式,PL/SQL不仅简化了数据验证平台的架构,提升了系统的可靠性,也使得数据处理更加高效和可控...

    论村民委员会的法律主体地位.docx

    未来立法完善的方向可能是强化村民会的法律地位,使其在必要时能够代表村庄集体参与诉讼,同时也要保障村民会议的权力,确保村民参与自治事务的积极性。 总结来说,村民委员会作为农村基层自治组织,其法律主体地位...

    ONE ON ONE 中文版第二部分

    9:数据装载 10:优化策略和工具 11:优化器方案稳定性 12:分析函数 13:物化试图 14:分区 15:自治事务 16:动态SQL 17:intermedia 18:基于C的外部过程 19:JAVA存储过程 20:使用对象关系特性 21:精细存取控制...

    ORACLE之常用FAQ V1.0(整理)

    - **解答:** 自治事务是一种特殊的事务类型,它不受外部事务的影响,即使外部事务失败,自治事务也可以正常提交。在 PL/SQL 中,可以通过 DECLARE 或者 BEGIN 块来声明自治事务。示例代码如下: ```plsql DECLARE...

Global site tag (gtag.js) - Google Analytics