我们遇到以下触发器问题。当没有新UPDATEPROCESSINFO
的行时,我们想在INSTANCEID
表中插入一行,并为下一个更新它。
但我们惊讶地发现有时候我们有多行具有相同的INSTANCEID
。是因为它非常快吗?如何防止这种情况发生?我们的目标是每INSTANCEID
行一行。
感谢您的帮助
create or replace TRIGGER TRIG_UPDATE_PROCESS_INFO
AFTER INSERT ON PROCESSSTEP
FOR EACH ROW
DECLARE
AUDIT_TIME TIMESTAMP(6);
BEGIN
SELECT MAX(LASTUPDATETIME)
INTO AUDIT_TIME
FROM UPDATEPROCESSINFO
WHERE INSTANCEID = :NEW.INSTANCEID;
IF AUDIT_TIME IS NULL THEN
INSERT INTO UPDATEPROCESSINFO
(INSTANCEID, STEPID, STEPSTATUS, STEPITERATION, LASTUPDATETIME)
VALUES
(:NEW.INSTANCEID, :NEW.STEPID, :NEW.STATUS, :NEW.STEPITERATION, :NEW.AUDITTIMESTAMP);
ELSIF :NEW.AUDITTIMESTAMP > AUDIT_TIME THEN
UPDATE UPDATEPROCESSINFO
SET STEPID = :NEW.STEPID,
LASTUPDATETIME = :NEW.AUDITTIMESTAMP,
STEPSTATUS = :NEW.STATUS,
STEPITERATION = :NEW.STEPITERATION
WHERE INSTANCEID = :NEW.INSTANCEID;
END IF;
END;
答案 0 :(得分:1)
这可能正在发生,因为您有多个会话插入到PROCESSSTEP中以获得相同的INSTANCEID。如果两个会话几乎同时插入PROCESSSTEP,并且他们都没有提交他们的更改,那么两个会话都不会"看到"其他的更改,都会认为UPDATEPROCESSINFO中不存在一行。
在我看来,这个设计似乎有问题。我建议将其更改为具有PROCESS_STEP_HISTORY表,并且在完成该过程中的每个步骤时,将一行插入到PROCESS_STEP_HISTORY中以记录已完成的过程步骤的信息。然后,当需要找到关于" last"的信息时已完成的步骤,它将执行类似
的操作SELECT a.*
FROM (SELECT *
FROM PROCESS_STEP_HISTORY h
WHERE INSTANCE_ID = whatever
ORDER BY LASTUPDATETIME DESC) a
WHERE ROWNUM = 1
它还具有保留过程中每个步骤的信息的优点,这可能证明是有用的。
我也不建议使用触发器来做这类事情。这是业务逻辑,将业务逻辑放入触发器永远不是一个好主意。
祝你好运。