oracle事务隔离级别_笔记11:重启动的相关知识点
可以观察一个有意思的情况,即使语句本身不一定导致重启动,触发器本身也可能导致发生重启动,一般来讲,UPDATE或DETELE语句的WHERE子句中引用的列能用于确定修改是否需要重启动。Oracle使用这些列完成一个一致读,然后以当前模式获取块时,如果检测到任何列有修改,就会重启动这个语句。一般来讲,不会检查行中的其他列。例如,下面重新运行前面的例子,这里使用WHERE Y>0来查找这两个会话中的行。
sys@ORCL>conn scott/tiger
Connected.
scott@ORCL>update t set x=x+1 where y>0;
old.x=2,old.y=1
new.x=3,new.y=1
1 row updated.
查看Y值时,Oracle为什么会把触发器触发两次?它会检查整个行吗?从输出结果可以看到,尽管我们在搜索Y>0,而且根本没有修改Y,但是更新确实重启动了,触发器又触发了两次。不过倘若重新创建触发器,只打印出它已触发这个事实就行了,而不再引用:OLD和:NEW值:
scott@ORCL>create or replace trigger t_bufer
2 before update on t for each row
3 begin
4 dbms_output.put_line('fired');
5 end;
6 /
Trigger created.
scott@ORCL>update t set x=x+1;
fired
1 row updated.
再到第二个会话中,运行更新后,可以观察到它会阻塞。提交阻塞会话后,可以看到以下输出:
第一个会话:
scott@ORCL>commit;
Commit complete.
第二个会话:
sys@ORCL>conn scott/tiger
Connected.
scott@ORCL>update t set x=x+1 where y>0;(此时会阻塞,第一个会话commit后,才继续)
fired
1 row updated.
这一次触发器只触发了一次,而不是两次。这说明,:NEW和:OLD列值在触发器中引用时,也会被Oracle用于完成重启动检查。在触发器中引用:NEW.X和:OLD.X时,会比较X的一致读值和当前读值,并发现二者不同。这就会带来一个重启动。从触发器将这一列的引用去掉后,就没有重启动了。
所以,对此的原则是:WHERE子句中查找行所用的列集会与行触发器中引用的列进行比较。行的一致读版本会与行的当前读版本比较,只要有不同,就会重启动修改。
本文来源 我爱IT技术网 http://www.52ij.com/jishu/5228.html 转载请保留链接。
- 评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)
-
