文档解释
ORA-04091: table string.string is mutating, trigger/function may not see it
Cause: A trigger (or a user defined plsql function that is referenced in this statement) attempted to look at (or modify) a table that was in the middle of being modified by the statement which fired it.
Action: Rewrite the trigger (or function) so it does not read that table.
这是一个Oracle数据库的触发器/函数调用时可能会遇到的异常,表示在当前调用过程中,数据表的内容不允许变更,但该数据表正在被其他会话更新,从而引发了这个异常。
官方解释
这是一个通用的错误,不仅仅是DML操作可以引发此错误,而且DDL操作也可能引发此错误,该错误表明一个事务正在更新一个表,而另一个事务正在使用这个表进行查询/更新/删除/插入等操作,从而导致数据不一致性。
常见案例
1.在编写存储过程时,存储过程本身或其他存储过程执行了DML操作,而另一个过程也有存储过程正在调用它,或另外一个连接对表进行更新操作。
2.在编写触发器时,触发器执行更新表的DML语句,而另一个会话也正在对这个表进行操作。
正常处理方法及步骤
1.确认被调用的存储过程或触发器文件。
2.查看程序中是否使用了表锁定来避免变异表,如果没有,请立即添加表锁定。
3.检查可能导致表变异的操作,也许是另一个连接/程序/触发器正在对相同的表进行DML操作,或者存在太多的更新操作。
4.查询V$LOCK表,查看是否有人正在对这张表加上了锁定,若有,请确认是否是造成ORA-04091错误的根本原因,并询问锁定此表的会话,作出相应处理。
5.考虑在使用支持FOR UPDATE SKIP LOCKED关键字的游标/PL/SQL循环结构,以及调用它们的函数或存储过程来处理ORA-04091,以解决DML操作可能导致的变异表错误。
6.如果错误被多次发生,也可以尝试更改环境参数_enable_DDL_logging(默认值是false),以跟踪DDL操作。