创建一个触发器为tr_test,执行完成下面的操作后,执行报错:ORA-04091: table is mutating, trigger/function may not see it
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;
mutating table是指一个当前正在被update,delete,insert语句修改的表,如果在一个行政级别的trigger中读取或修改一个mutating table,则往往会遇到ORA-04091问题。如果在trigger中使用了select或dml语句访问trigger所在的表,则就会收到这种错误。
note:dml语言:主要是指对数据的增删改查(insert/delete/update/select)操作。
解决方法是把update作为一个单独的事务来执行,即在declare后面添加PRAGMA AUTONOMOUS_TRANSACTION,在update操作后执行commit操作这样就可以解决这种问题,但实际上这种逻辑的语句应该写在存储过程中,尽量不要在触发器中多次使用此方法。特别是当其作为单独的事务对同一表进行操作的时候,会造成死锁的问题。
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 ;
commit;
end tr_test;
AUTONOMOUS_TRANSACTION是指在function,procedure,trigger等subprograms中对事务进行自治管理,当在别的pl/sql block里取调用这些subprograms的时候这些subprograms并不随着父pl/sql block的失败而回滚,而是自己管自己commit;