我们的情况有些特殊。我们正在完全重建一个旧的应用程序。但是,由于我们仍然必须同时支持这两个应用程序,因此有一些触发器可以在将数据保存到新模型后将其传输到旧模型。触发器如下所示:
*关于触发器的简短提示。首先查询对象的类型(因为UUID是固定的,所以可以),然后检查记录是否存在,然后根据操作删除或更新已存在的父记录上的值。
DeclARE
T_TELEFONNUMMER_ID VARCHAR2(50);
T_PERSON_ID VARCHAR2(50);
T_SOEMMERUNG_ID VARCHAR2(50);
T_TELEFONTYP_ID VARCHAR2(50);
T_REIHENFOLGE NUMber(10);
T_ROW_EXISTS NUMber(1);
T_ROW_EXISTS_SOMM NUMber(1);
T_TELEFONTYP VARCHAR2(50);
BEGIN
IF (INSERTING
OR UPDATING)
AND :NEW.PERSON_ID IS NULL
THEN
RETURN;
END IF;
IF DELETING
AND :OLD.PERSON_ID IS NULL
THEN
RETURN;
END IF;
IF INSERTING
THEN
T_TELEFONNUMMER_ID := :NEW.ID;
T_PERSON_ID := :NEW.PERSON_ID;
T_TELEFONTYP_ID := :NEW.TELEFONTYP_ID;
T_REIHENFOLGE := :NEW.REIHENFOLGE;
T_SOEMMERUNG_ID := :NEW.SOEMMERUNG_ID;
ELSE
T_TELEFONNUMMER_ID := :OLD.ID;
T_PERSON_ID := :OLD.PERSON_ID;
T_TELEFONTYP_ID := :OLD.TELEFONTYP_ID;
T_REIHENFOLGE := :OLD.REIHENFOLGE;
T_SOEMMERUNG_ID := :OLD.SOEMMERUNG_ID;
END IF;
IF SUBSTR(T_TELEFONTYP_ID,1,36) = '6518f45b-081d-81d2-fbe0-30100007ff98'
THEN
IF T_REIHENFOLGE = 1
THEN
T_TELEFONTYP := 'Telefon';
ELSIF T_REIHENFOLGE = 2
THEN
T_TELEFONTYP := 'Telefon2';
ELSIF T_REIHENFOLGE IS NULL
THEN
RAISE_APPLICATION_ERROR(-20500,'Es wurde eine Telefonnummer vom Typ Telefon übergeben,aber keine Reihenfolge. Ohne diese kann nicht in die OT-Tabelle gespeichert werden.');
ELSE
RAISE_APPLICATION_ERROR(-20500,'Die Reihenfolge "' || T_REIHENFOLGE || '" wird nicht behandelt.');
END IF;
ELSIF SUBSTR(T_TELEFONTYP_ID,36) = '6518f45b-081f-81f2-fbe0-30100007ff98'
THEN
T_TELEFONTYP := 'Mobile';
ELSIF SUBSTR(T_TELEFONTYP_ID,36) = '6518f45b-0821-8212-fbe0-30100007ff98'
THEN
T_TELEFONTYP := 'Fax';
ELSIF SUBSTR(T_TELEFONTYP_ID,36) = '6518f45b-0821-8212-fbe0-30100007ff99'
THEN
T_TELEFONTYP := 'Alptelefon';
ELSIF T_TELEFONTYP IS NULL
THEN
RAISE_APPLICATION_ERROR(-20500,'Für die Telefontyp-ID "' || T_TELEFONTYP_ID ||
'" konnte kein passender Typ im Trigger gefunden werden.');
END IF;
IF T_TELEFONTYP = 'Alptelefon'
THEN
SELECT COUNT(*)
INTO T_ROW_EXISTS_SOMM
FROM HEARTCORE.OT_SOMM2000 S
WHERE S.RORM_SOEMMERUNG_ID = T_SOEMMERUNG_ID;
ELSE
SELECT COUNT(*)
INTO T_ROW_EXISTS
FROM HEARTCORE.OT_ADRESSEN A
WHERE A.RORM_PERSON_ID = T_PERSON_ID;
END IF;
IF DELETING
THEN
IF T_ROW_EXISTS > 0
THEN
CASE T_TELEFONTYP
WHEN 'Telefon' THEN UPDATE HEARTCORE.OT_ADRESSEN A
SET A.TELEFON_NR = NULL,A.RORM_TELEFONNUMMER1_ID = NULL,A.RORM_TELEFONTYP1_ID = NULL
WHERE A.RORM_PERSON_ID = T_PERSON_ID
AND JAHR = 2019;
RETURN;
WHEN 'Telefon2' THEN UPDATE HEARTCORE.OT_ADRESSEN A
SET A.TELEFON_NR2 = NULL,A.RORM_TELEFONNUMMER2_ID = NULL,A.RORM_TELEFONTYP2_ID = NULL
WHERE A.RORM_PERSON_ID = T_PERSON_ID
AND JAHR = 2019;
RETURN;
WHEN 'Mobile' THEN UPDATE HEARTCORE.OT_ADRESSEN A
SET A.TELEFON_NR3 = NULL,A.RORM_TELEFONNUMMER3_ID = NULL,A.RORM_TELEFONTYP3_ID = NULL
WHERE A.RORM_PERSON_ID = T_PERSON_ID
AND JAHR = 2019;
RETURN;
WHEN 'Fax' THEN UPDATE HEARTCORE.OT_ADRESSEN A
SET A.TELEFAX = NULL,A.RORM_TELEFONNUMMER4_ID = NULL,A.RORM_TELEFONTYP4_ID = NULL
WHERE A.RORM_PERSON_ID = T_PERSON_ID
AND JAHR = 2019;
RETURN;
END CASE;
ELSIF T_ROW_EXISTS_SOMM > 0
THEN
CASE T_TELEFONTYP
WHEN 'Alptelefon' THEN UPDATE HEARTCORE.OT_SOMM2000 S
SET S.ALPTEL = NULL,S.RORM_TELEFONNUMMER_ID = NULL
WHERE S.RORM_SOEMMERUNG_ID = T_SOEMMERUNG_ID
AND JAHR = 2019;
RETURN;
END CASE;
ELSE
RAISE_APPLICATION_ERROR(-20500,'Es konnte kein Datensatz in OT_ADRESSEN gefunden werden,dessen RORM_PERSON_ID = ' || T_PERSON_ID || ' entspricht.');
END IF;
END IF;
IF UPDATING OR INSERTING
THEN
IF T_ROW_EXISTS_SOMM > 0
THEN
CASE T_TELEFONTYP
WHEN 'Alptelefon' THEN UPDATE HEARTCORE.OT_SOMM2000 S
SET S.ALPTEL = :NEW.NUMMER,S.RORM_TELEFONNUMMER_ID = :NEW.ID
WHERE S.RORM_SOEMMERUNG_ID = T_SOEMMERUNG_ID
AND JAHR = 2019;
RETURN;
END CASE;
ELSIF T_ROW_EXISTS > 0
THEN
CASE T_TELEFONTYP
WHEN 'Telefon' THEN UPDATE HEARTCORE.OT_ADRESSEN A
SET A.TELEFON_NR = :NEW.NUMMER,A.RORM_TELEFONNUMMER1_ID = :NEW.ID,A.RORM_TELEFONTYP1_ID = :NEW.TELEFONTYP_ID
WHERE A.RORM_PERSON_ID = T_PERSON_ID
AND JAHR = 2019;
RETURN;
WHEN 'Telefon2' THEN UPDATE HEARTCORE.OT_ADRESSEN A
SET A.TELEFON_NR2 = :NEW.NUMMER,A.RORM_TELEFONNUMMER2_ID = :NEW.ID,A.RORM_TELEFONTYP2_ID = :NEW.TELEFONTYP_ID
WHERE A.RORM_PERSON_ID = T_PERSON_ID
AND JAHR = 2019;
RETURN;
WHEN 'Mobile' THEN UPDATE HEARTCORE.OT_ADRESSEN A
SET A.TELEFON_NR3 = :NEW.NUMMER,A.RORM_TELEFONNUMMER3_ID = :NEW.ID,A.RORM_TELEFONTYP3_ID = :NEW.TELEFONTYP_ID
WHERE A.RORM_PERSON_ID = T_PERSON_ID
AND JAHR = 2019;
RETURN;
WHEN 'Fax' THEN UPDATE HEARTCORE.OT_ADRESSEN A
SET A.TELEFAX = :NEW.NUMMER,A.RORM_TELEFONNUMMER4_ID = :NEW.ID,A.RORM_TELEFONTYP4_ID = :NEW.TELEFONTYP_ID
WHERE A.RORM_PERSON_ID = T_PERSON_ID
AND JAHR = 2019;
RETURN;
END CASE;
ELSE
RAISE_APPLICATION_ERROR(-20500,dessen RORM_PERSON_ID = ' || T_PERSON_ID || ' entspricht.');
END IF;
END IF;
END;
曾经被写入一个数据集中的问题现在是四个或五个单独的对象。这些对象包含在父对象的列表中。问题可能是现在每个人都试图同时写入同一数据集。例如,如果我现在在前端中添加和删除两个对象,则会执行对REST API的两次调用(addChild和remove Child),这通常会导致此错误:
ORA-00060: deadlock detected while waiting for resource
我该怎么办?由于我没有任何经验,因此不确定是否应该在Oracle Trigger或Hibernate中解决该问题?我们以前从未遇到过此问题。 据我所知,我们尚未实现任何锁定等功能。如果记录已锁定,是否可以排队或等待?还是最简单的解决方案是什么?感觉尝试立即失败了。
我们正在使用Spring Boot 2.1.5.RELEASE
,它使用Hibernate 5.3.10
。作为数据库,我们使用Oracle 12c
。