zoukankan      html  css  js  c++  java
  • 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避免错误.

    [sql] view plain copy
     
    1. create or replace trigger tr_test  
    2. after insert   
    3. on test  
    4. for each row  
    5. begin  
    6.    update test set column2=123 where column1=:new.column1  
    7. end tr_test;  


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

    那应该怎么改呢?

    [sql] view plain copy
     
    1. create or replace trigger tr_test  
    2. before insert  
    3. on test  
    4. for each row  
    5. begin  
    6.    :new.column2:=123  
    7. end tr_test;  

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

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

    还有一种方法是加 PRAGMA AUTONOMOUS_TRANSACTION;

    [sql] view plain copy
     
    1. create or replace trigger tr_test  
    2. after insert   
    3. on test  
    4. for each row  
    5. declare  
    6. PRAGMA AUTONOMOUS_TRANSACTION;  
    7. begin  
    8.    update test set column2=123 where column1=:new.column1  ;
    9.    commit;
    10. end tr_test;  

    这样也可以执行成功。

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

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

  • 相关阅读:
    连续3年!SpreadJS 纯前端表格控件荣获“中国优秀软件产品”
    终于有一款组件可以全面超越Apache POI
    List<Object> 多条件去重
    xml文档的解析并通过工具类实现java实体类的映射:XML工具-XmlUtil
    soap get/post请求
    map转java对象
    springboot postman 对象里传时间格式问题
    spring boot的多环境部署
    Hibernate 之 @Query查询
    利用maven命令将外部jar包导进maven仓库
  • 原文地址:https://www.cnblogs.com/soundcode/p/6171050.html
Copyright © 2011-2022 走看看