我有一个表tab1 (t_id, status)
,tab2 (id, t_id, status)
其中t_id.tab2
有外键引用tab1.t_id
。
S1获取承担Oracle会话SELECT FOR UPDATE NOWAIT
中的记录锁定tab1
有t_id=123
。
当NOWAIT
s1仍然保持锁定时tab1
,另一个会话s2是否可以tab2
用tab2.t_id=123
(FK)更新记录?
正如注释中所指出的那样,用locking read(SELECT ... FOR UPDATE
)语句发出的行锁不会传播到声明的子表中FOREIGN KEY
。
这是一个演示此的示例:
-- Set up schema
CREATE TABLE tab1 (t_id NUMBER(10), status VARCHAR2(10), PRIMARY KEY (t_id));
CREATE TABLE tab2 (id NUMBER(10), t_id NUMBER(10), status VARCHAR2(10),
PRIMARY KEY (id),
CONSTRAINT fk_tab1 FOREIGN KEY (t_id) REFERENCES tab1 (t_id));
INSERT INTO tab1 (t_id, status) VALUES (123, 'Status1');
INSERT INTO tab1 (t_id, status) VALUES (234, 'Status1');
INSERT INTO tab2 (id, t_id, status) VALUES (1, 123, 'Status2');
INSERT INTO tab2 (id, t_id, status) VALUES (2, 234, 'Status2');
COMMIT;
以下脚本使用该AUTONOMOUS_TRANSACTION
实用程序来发出新事务,该脚本成功执行(例如在Oracle SQLDeveloper中):
SET autocommit 0;
SELECT * FROM tab1 WHERE t_id=123 FOR UPDATE NOWAIT;
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
UPDATE tab1 SET status = 'Status2' WHERE t_id = 234;
UPDATE tab2 SET t_id = 234, status = 'Status2' WHERE t_id = 123;
COMMIT;
END;
因此,可以更改中的其他行tab1
以及tab2
指向中的锁定行的外键列tab1
。
如预期的那样,尝试更新锁定的行:
SELECT * FROM tab1 WHERE t_id=123 FOR UPDATE NOWAIT;
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
UPDATE tab1 SET status = 'Status2' WHERE t_id = 123;
COMMIT;
END;
...将失败并显示错误消息:
ORA-00060:等待资源时检测到死锁
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句