使用触发器更新表时锁定

时间:2016-10-21 10:29:51

标签: oracle plsql triggers

我有一个表(T1),更新后有一个触发器。此触发器查找某些值,然后更新其他表(T2)

CREATE OR REPLACE TRIGGER t1_AIR AFTER UPDATE ON t1 FOR EACH ROW

DECLARE
    PRAGMA AUTONOMOUS_TRANSACTION;
    v_dF1       DATE;
    v_dF2       DATE;
    v_nDays     NUMBER;
    v_cReg      VARCHAR2(50);

BEGIN

IF :NEW.BN_BE_ESTADO not in ('PEN', 'ERR', 'BAJ') THEN

    v_nDays := F_GET_PARAM(NULL, NULL, 'X_DAYS');

    PCK_AUX.PR_GET_F1(:NEW.F_A, v_dF1, v_cReg);
    PCK_AUX.PR_GET_F2(:NEW.F_A, v_dF2);

    UPDATE T2
    SET F_F1 = TRUNC(v_dF1),
        F_F2 = TRUNC(v_dF2),
        F_F_END = PCK_AUX.FU_GET_F_END(v_dF2+1, v_nDays),
        F_N_REG = v_cReg
    WHERE F_ID = :NEW.F_B;

END IF;

EXCEPTION
        WHEN OTHERS THEN
         NULL;                   
END;

但是当我更新T1时,它会在两个表中生成锁(t1和t2)......有谁知道为什么?

感谢所有

1 个答案:

答案 0 :(得分:3)

更新表时,将获取行共享(RM)和行独占模式(RX)中的行级(TX)锁和表锁。

存在行级锁定,因此其他会话无法修改正在更新的行。不同模式下的表锁是为了保护您的表结构免受修改,而DML语句(在您的情况下为update)正在进行中。

所以是的,在您的情况下,正在更新的行将被锁定在table 1 and table 2和表锁定中,将以行共享和行独占模式保存。

关于你的触发器......

为什么autonomous transaction pragma在那里?除非您使用该触发器进行日志记录,例如,当您必须提交主事务是否成功时,您实际上不需要此pragma。正如@William Robertson绝对正确地指出,如果使用autonomous transaction你必须提交这个自治事务,否则将引发ORA-06519

重新考虑when others then null语句的使用 - 最好不要隐藏但重新引发可能产生的任何异常。