oracle restart:语句重新执行

今天看了tom大师关于sql restart的博客,收益颇深。鉴于翻墙的繁琐和以后查阅的方便,将主要内容总结至此。大家也可以通过如下地址查看原博文及精彩点评(需要翻墙哦)。

http://tkyte.blogspot.com/2005/08/something-different-part-i-of-iii.html

http://tkyte.blogspot.com/2005/08/part-ii-seeing-restart.html

http://tkyte.blogspot.com/2005/09/part-iii-why-is-restart-important-to.html

大家都知道oracle通过一致性读来防止阻塞并为查询提供结果。但是对于写或者说编辑操作,oracle是怎样处理的那?例如下面的语句:
update t set x=2 where y=5;
对于这样的语句,oracle首先会根据语句的运行起始时间T1和WHERE条件进行基于T1的一致性查询操作,找出y=5的所有记录,然后对这些记录进行更新操作。那么这里就存在一个问题,假设在T2时间,oracle修改到记录R,如果在T1和T2之间的时间段里,某个用户进程修改了记录R并进行了提交,此时oracle会做如何处理那?我们知道,读操作我们可以基于以往时间点构造一致性块,但是对于写操作,我们必须对当前块进行操作。


首先我们在表tab上创建触发器

SQL> create or replace trigger tab_tri
  2  before update on tab for each row
  3  begin
  4  dbms_output.put_line(' old.x = '||:old.x||',old.y ='||:old.y);
  5  dbms_output.put_line(' new.x = '||:new.x||',new.y ='||:new.y);
  6  end;
  7  /
session1:更新某记录,不提交

SQL> update tab set x=2 where y=1;
session2:更新相同记录,进程被阻塞

SQL> update tab set x=3 where y=1;
session2:session1提交后

SQL> update tab set x=3 where y=1;
old.x = 1,old.y =1
new.x = 3,new.y =1
old.x = 2,old.y =1
new.x = 3,new.y =1

已更新 1 行。

从这里可以看出,如果更新R时,oracle发现R已经被修改过,那么oracle会重新执行update语句。

下面让我们修改一下触发器

SQL> create or replace trigger tab_tri
  2  before update on tab for each row
  3  begin
  4  dbms_output.put_line('aaaaa');
  5  end;
  6  /
session2:在session1提交后:

SQL> update tab set x=3 where y=1;
aaaaa
已更新 1 行。
非常奇怪?这里update语句并没有重新执行
下面在来改变一下执行语句:
sesion1:

SQL> update tab set y=2 where y=1;

已更新 1 行。
session2:

SQL> update tab set x=3 where y>0;
aaaaa
aaaaa

这里update语句再次重新执行。好,我们总结如下:
如果在update(delete没有测试,估计应该是相同的)语句的执行过程中,待操作记录发生了改变,并且被改变的列在where子句或者row触发器(after or before)的内部使用:old或者:new引用过,那么update语句会将之前的操作回滚并重新执行。这也是after触发器效率高于before触发器的一个原因,因为即便update重新执行,after触发器只执行一次,而befer触发器会执行两次。如果发生了restart,oracle会在第二次执行的过程中尝试使用select for update来进行操作,以避免发生再一次的restart。但是即便使用select for update ,依然有可能发生restart。


下面看一下restart产生的影响:
1:如果触发器维护plsql中的全局变量,那么全局变量可能是不准确的
2:任何utl_函数,例如UTL_FILE, UTL_HTTP, UTL_SMTP,可能会执行两次,因此这些函数时非事务性的,无法回滚
3:自治事务当然也会受影响而执行多次







  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值