Oracle死锁触发器

Oracle死锁触发器,oracle,plsql,database-trigger,Oracle,Plsql,Database Trigger,我有一个程序。 表T1、T2和触发器TRG1 以下是触发事件: CREATE OR REPLACE TRIGGER AFTER UPDATE OF RECORD_STATUS ON T1 WHEN (NEW.RECORD_STATUS='U') BEGIN . --Calling Procedure P1(); . END; 我正在用参数调用一个过程。在程序P1中,我使用这些参数从T1中选择数据,进行一些验证并插入T2 成功插入后,我正在更新过程中的记录_STATUS='I' 现在我执行以下声

我有一个程序。 表T1、T2和触发器TRG1 以下是触发事件:

CREATE OR REPLACE TRIGGER
AFTER UPDATE OF RECORD_STATUS
ON T1 WHEN (NEW.RECORD_STATUS='U')
BEGIN
.
--Calling Procedure
P1();
.
END;
我正在用参数调用一个过程。在程序P1中,我使用这些参数从T1中选择数据,进行一些验证并插入T2

成功插入后,我正在更新过程中的记录_STATUS='I'

现在我执行以下声明:

UPDATE T1 SET RECORD_STATUS='U'
因为触发器事件发生在这里,所以它正在调用我的过程,并且在过程内部,因为我正在更新同一列,所以触发器正在触发并导致死锁。请帮我做这件事


提前感谢。

首先,建议不要使用触发器,除非你不顾一切

如果您已经在更新存储过程中的表,请将逻辑添加到P1过程中,或者创建具有附加功能的第二个过程并从P1调用它

良好的公民身份是数据库开发的一部分。这些表上的所有事务都应遵循相同的顺序。使用触发器更新同一个表是不好的


如果您真的必须这样做,您可以尝试的一件事是使用

首先,避免在触发器中使用业务逻辑,这看起来像是应用程序设计缺陷。对触发器所有者的列的任何引用都应在触发器中使用:NEW和:OLD前缀,而不是在触发器中或您正在执行的任何其他操作中直接对它们使用select或update查询。:NEW和:OLD值在语句触发器中不可用,它们仅存在于行级触发器中,也就是说,对于每一行子句,表有任何位图索引,或者您是否在过程中运行自治事务?@WernfriedDomscheit:Right。现在我注意到for每一行都丢失了,这意味着when子句不应该让触发器编译。听起来你的逻辑有点复杂,我们很难理解你想做什么。我建议您发布代码的最简单版本。向下投票。可以说,自治事务与触发器一样被滥用和滥用。这并不是说一个人不能同时使用它们来设计一个合法的设计,但我读到这篇文章是对自主交易的无保留认可,这是一种修复基于触发器的可疑设计的方法。触发器有其用途。自治事务有其用途。两者都可能被过度使用,但都不是另一个的替代品。我在处理更新的过程中使用了一个巨大的事务。然而,在仔细检查了所有可能性之后,我放弃了触发器,因为它导致了递归触发器。我创建了一个包装程序来调用这个过程。