ORA-04091: table is mutating, trigger/function may not see it

今天在论坛里发现了一个关于ORA-04091的老帖子,收获良多,特此整理一下

关于ORA-04091: table is mutating, trigger/function may not see it的分析


当DML操作触发trigger的时候,如果trigger的程序块中需要对当前表进行修改或查询的时候,就会报错
ORA-04091: table is mutating, trigger/function may not see it

这是有在被触发TRIGGER工作的时候,默认把当前表表锁死,不允许对其进行操作,所以trigger包含对当前表的DML操作就会报错,那怎么办?最常用的方法是通过修改SQL避免错误.

create or replace trigger tr_test
after insert 
on test
for each row
begin
   update test set column2=123 where column1=:new.column1
end tr_test;

这就是个典型的错误的例子,肯定会报错ORA-04091,这个trigger是为了修改新插入的行的某列,因为插入后当前表已经被锁死了,所以根本没有办法update,所以报错。

那应该怎么改呢?


create or replace trigger tr_test
before insert
on test
for each row
begin
   :new.column2:=123
end tr_test;

在出入前就修改好要修改的值,就不会报错了

但是这种方法浪费时间精力,更重要的并不是所有问题都可以找到这样的方法绕过去.

还有一种方法是加 PRAGMA AUTONOMOUS_TRANSACTION;

create or replace trigger tr_test
after insert 
on test
for each row
declare
PRAGMA AUTONOMOUS_TRANSACTION;
begin
   update test set column2=123 where column1=:new.column1
end tr_test;
这样也可以执行成功。

AUTONOMOUS_TRANSACTION是指在function,procedure,trigger等subprograms中对事务进行自治管理,当在别的pl/sql block里取调用这些subprograms的时候这些subprograms并不随着父pl/sql block的失败而回滚,而是自己管自己commit;

注意慎用AUTONOMOUS_TRANSACTION。一个DML可能触发很多次触发器,因此产生了大量独立的事务,很容易产生死锁。
ASKTOM上对AUTONOMOUS_TRANSACTION的看法是:唯一的用途就是作审计日志,其他一概不该使用。
有人建议是取消使用触发器,把你的业务逻辑写到存储过程去。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值