自治事务前的事务管理(一般事务管理)
像 DML 这样的数据库扣作都是在事务的上下文环境中执行的。事务是一个或多个 SQL 语句的序列,执行一定的工作逻辑单元。事务、定义的特定会话可以由 commit 和 rollback 操作进行控制。只要发生 commit 或 rollback 操作就会释放锁定资源的锁。
自治事务的定义和使用
自治事务是将单一的、完整的事务分割为多个子事务。控制从主事务( MT )转移到自治事务( AT )。一旦自治事务执行了,主事务就会恢复执行。自治事务独立于主事务, COMMIT 和 ROLLBACK 的范围仅仅限制在自治事务的上下文中。
自治事务的优点
1、 代码的模块人程度更高而且更简单。
2、 在触发器内执行 COMMIT
3、 从执行 DML 的 SQL 中调用用户自定义的函数。
将事务指定为自治事务
可以在代码的声明部分使用下面语句,以便在 PL/SQL 块中定义一个自治事务:
PRAGMA AUTONOMOUS_TRANSACTION
其中 pragma 关键字的作用是通知 PL/SQL 编译器,将声明它的这个 PL/SQL 代码块分割为一个自治的或独立的事务。定义自治事务时,要遵守以下几条规则:
1 、如果 PL/SQL 块是匿名的,那么该匿名 PL/SQL 块必须是一个顶层块。
2 、如果 PL/SQL 块不是匿名的,那么它必须作为包或存储过程序单元一部分的一个过程或函数。当在包中定义自治事务时,只有包中具体的函数或过程才能被指定为自治的的。
3 、 PL/SQL 块也可以是存储对象类型的一个方法
4 、 PL/SQL 块也可以是一个数据库触发器
一个例子程序
create or replace procedure writelog(
vid number,errtext varchar2
)
is
pragmaautonomous_transaction; -- 定义事务
begin
insert into t_log values(vid,errtext);
commit;
end;
create or replace procedure createuser(uid number ,vname varchar2,vsex varchar2)
is
begin
insertinto t_user values (uid,vname,vsex);
commit;
exception
whenothersthen
writelog(sqlcode,sqlerrm);
rollback;
end;
自治事务处理
主事务开始执行
主事务遇到一个对自治子程序的调用,这时主事务就暂停,将控制转移到自治例程中
自治事务开始执行
自治事务执行 commit 或 rollback 操作,这将结束当前自治事务。
主事务恢复
主事务结束
自治事务的一些关键问题
1、 带 ALTER SESSION 的自治事务
自治事务应该与主事务共享一个会话,因此通过 ALTER SESSION 语句,对该会话的任何修改,对自治事务和主事务应该都是可见的。但自治事务执行与主事务不同的上下文中。任何从自治块中引发的自治子程序调用都与自治事务共享相同的事务上下文。
2、 自治事务与死锁
必须以下面的这种方式定义自治事务:
不创建主事务对资源和锁的死锁。死锁在自治事务试图访问一个被主事务占用的资源时发生,这时主事务会挂起,直到自治事务结束。自治事务死等主事务释放资源,结果可能导致死锁。
3、 定义自治事务的条件
只有顶层匿名块才能包括 PRAGMA AUTONOMOUS_TRANSTRACTION
4、 COMMIT 或 ROLLBACK 行为与自治事务
自治事务是以 commit 或 rollback 语句结束的。因此,应该在自治事务程序的内部显式地包含一个 commit 或 rollback 语句。如果没有这样做,任何一个未确定的事务都会回滚。这是一个事务级的回滚,而不是一个语句级的回滚。
5、 异常与自治事务
当自治事务以一个异常的方式退出时,就发生一个事务级的回滚,自事事务中所有未确定的改变都会回滚 .
6、 多自治事务
一个自治事务的上下文中,初始化多个自治事务。可以在一个自治块内定义多个 commit 或 rollback 语句来完成这项任务,当包含一个 rollback 时,它就会属于当前事务,而不属于主事务。
7、 自治事务的并发问题
自治事务与主事务是并发运行的,初始化文件 init.ora 中的 transactions 参数决定着每个会话中并发事务的数量。 .
8、 通过自治事务和从 SQL 中调用用户自定义函数
通过自治事务,可以从 SQL 中调用用户自定义函数来执行 DML 操作。只需把用户自定义函数定义为自治事务,函数就变为可从 SQL 中调用的。
9、 自治事务和隔离等级
应该在自治事务中给出 commit 或 rollback 命令,一旦 commit 或 rollback 在自治事务内部执行,那些改变对主事务而言是可见。但是 oracle 也允许从主事务中通过设定主事务的隔离等级为 SERIALIZABLE ,而不是默认的 READ COMMITTED ,对主事务隐藏这些改变,这可以通过 Set TRANSCTION 语句完成,其语法如下:
Set transaction isolation level serializable;
关于隔离等级的问题,以下两点值得注意:
1 当自治事务以 commit 或 rollback 而结束时,由自治事务造成的改变对主事务以外的其它事务是可见的 .
2 设置隔离等级为 serializable ,对主事务隐藏自治事务的变化。直到主事务提交,主事务一旦提交,自治事务中的改变对自治事务也就可见。
10、 什么是隔离级别
隔离级别是一种处理修改数据库事务的方法,它影响到一个事务中的改变对另一个事务的可见性。 SQL92 中定义了 4 种隔离级别即:
READ UNCOMMITTED
REPEATABLE READ
READ COMMOTTED
SERIALIZABLE
些外 oracle 支持 READ COMMOTTED 和 SERIALIZABLE 两种隔离级别
Read committed :这种设置是 oracle 默认的 , 它使 oracle 查询可以看到查询之前提将近的数据。换句话说,这种模式的事务是基于每句一致的事务集的。
Serializable : 这种设置意味着一个事务中的所有语句,都在操作一个事务开始时的数据库映像中,这意味着没有 commit 之前,当前事务都不能看到其它事务所提交的数据。