Hibernate和Oracle-触发器中的死锁

我们的情况有些特殊。我们正在完全重建一个旧的应用程序。但是,由于我们仍然必须同时支持这两个应用程序,因此有一些触发器可以在将数据保存到新模型后将其传输到旧模型。触发器如下所示:

*关于触发器的简短提示。首先查询对象的类型(因为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

oye07 回答:Hibernate和Oracle-触发器中的死锁

暂时没有好的解决方案,如果你有好的解决方案,请发邮件至:iooj@foxmail.com
本文链接:https://www.f2er.com/3104331.html

大家都在问