【发布时间】:2010-09-27 10:04:05
【问题描述】:
我最近开始研究一个大型复杂的应用程序,由于这个错误,我刚刚被分配了一个错误:
ORA-04091: table SCMA.TBL1 is mutating, trigger/function may not see it
ORA-06512: at "SCMA.TRG_T1_TBL1_COL1", line 4
ORA-04088: error during execution of trigger 'SCMA.TRG_T1_TBL1_COL1'
有问题的触发器看起来像
create or replace TRIGGER TRG_T1_TBL1_COL1
BEFORE INSERT OR UPDATE OF t1_appnt_evnt_id ON TBL1
FOR EACH ROW
WHEN (NEW.t1_prnt_t1_pk is not null)
DECLARE
v_reassign_count number(20);
BEGIN
select count(t1_pk) INTO v_reassign_count from TBL1
where t1_appnt_evnt_id=:new.t1_appnt_evnt_id and t1_prnt_t1_pk is not null;
IF (v_reassign_count > 0) THEN
RAISE_APPLICATION_ERROR(-20013, 'Multiple reassignments not allowed');
END IF;
END;
该表有一个主键“t1_pk”,一个“约会事件 id”
t1_appnt_evnt_id 和另一列“t1_prnt_t1_pk”可能会或可能会
不包含另一行的t1_pk。
看来触发器正试图确保没有其他人使用
相同的t1_appnt_evnt_id 引用了同一行,引用了另一行,如果这一行引用了另一行。
DBA 对错误报告的评论说“删除触发器,并在代码中执行检查”,但不幸的是,他们在 Hibernate 之上有一个专有的代码生成框架,所以我什至无法弄清楚它实际上被写出来的地方,所以我希望有一种方法可以使这个触发器工作。有吗?
【问题讨论】:
-
只在代码中强制执行这样的规则是个坏主意——多个同时更新很难处理。如果您在代码中同步,您最终可能会在该代码和数据库锁之间出现肮脏的死锁。
-
底线 - Oracle 触发器很糟糕。除了像更新序列值或“updated_by”类型字段这样简单的事情外,像瘟疫一样避免它们。他们的触发器在 90 年代很糟糕,现在很糟糕。
标签: oracle hibernate triggers ora-04091