我有一个表(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)......有谁知道为什么?
感谢所有
答案 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
语句的使用 - 最好不要隐藏但重新引发可能产生的任何异常。