您的位置:首页 > 数据库 > Oracle

关于oracle中触发器触发时,报“表发生了变化,触发器或函数不能读它”错误

2016-08-18 00:03 288 查看
关于oracle中触发器触发时,报“表发生了变化,触发器或函数不能读它”错误最近遇到了一个关于在触发器中操作本表时报“表发生了变化,触发器或函数不能读它”错误的,问题查找各种博客知道。有了一些理解。下面总结一下:1.在同一个事务中,触发器不能读取或更新触发语句的任何变异表也包括触发表本身,这些限制约束适用于所有行级触发器.2.但是可以使用自治事物,解决这个问题。如:create table tb_test(tid number primary key,username varchar2(10),pwd varchar2(10));create or replace trigger tri_testafter update on tb_testfor each rowdeclarev_ddd tb_test.username%type;pragma autonomous_transaction;beginselect username into v_ddd from tb_test where tid=:new.tid;dbms_output.put_line(v_ddd);commit;end;  上面如果不用自治事物就会报“表发生了变化,触发器或函数不能读它”错误但是上面很容易产生死锁的问题,如果在触发其中,对触发该触发器的记录进行update,或者delete操作时,会发生死锁。如:
create or replace trigger tri_testafter update on tb_testfor each rowdeclarev_ddd tb_test.username%type;pragma autonomous_transaction;beginupdate tb_test set username='eee' where tid=:new.tid;commit;end;update tb_test set username='111' where tid=1;ORA-0006O:等待资源时检测到死锁
但是如果不是对触发该触发器的记录,做这些操作则不会报错。原因如下:update对锁的流程:当sql发出一个update请求之后,数据库会对表中的每条记录加上U锁。然后数据库会根据where条件,将符合条件的记录转换为X锁。对不满足条件的记录释放U锁。假设有A,B事务,发生下面情况,就会发生死锁。而这也解释了,为什么如果在触发其中,对触发该触发器的记录进行update,或者delete操作时,会发生死锁。而对其他记录进行进行update,或者delete操作时,没有发生死锁的现象。1、执行A的查询的时候,数据库将所有的记录加上U锁,然后将将不是c2的记录全部释放U锁。对满足条件的数据添加X锁。此时,A事务还没有结束,A不会释放此时的X锁。 2、B查询的时候,B会对表中的所有记录添加U锁,因为B查询要用到t_table这张表,B查询c1的时候,满足条件给c1添加上X锁。执行c=2的时候,要给c2加U锁,此时该记录被A添加了X锁。所以B查询需要等A释放的X锁,才可以执行。此时B等待。B要等待A释放c2的X锁 3、A的阻塞释放之后,A要进行第二条查询。这个时候A要对符合第二个查询条件的记录添加X锁。当执行c1的时候,c1刚才被B添加了X锁。所以此时A等待。A在等待B的U锁释放。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐