我有Oracle Database 11g企业版11.2.0.1.0版。 我有父表t1和t2与外键引用t1(col1)。 我想知道锁定的原因是什么? 请检查我做了什么...
SQL> create table t1(col1 char(1), primary key(col1));
Table created.
SQL> insert into t1 values('1');
1 row created.
SQL> insert into t1 values('2');
1 row created.
SQL> insert into t1 values('3');
1 row created.
SQL> insert into t1 values('4');
1 row created.
SQL> insert into t1 values('5');
1 row created.
SQL> commit;
Commit complete.
SQL> create table t2(col1 char(1), col2 char(2), foreign key(col1) references t1(col1));
Table created.
SQL> insert into t2 values('1','0');
1 row created.
SQL> commit;
Commit complete.
SQL> update t2 set col2='9'; --not committed yet!
1 row updated.
SQL> delete from t1; -- Lock happens here!!!
SQL> commit;
Commit complete.
delete from t1 -- The error occurs after I commit updating query in session 1.
*
ERROR at line 1:
ORA-02292: integrity constraint (KMS_USER.SYS_C0013643) violated - child record found
有人能解释我为什么会这样吗?
答案 0 :(得分:3)
delete from t1;
尝试锁定子表T2。如果会话正在等待整个表锁,它甚至无法删除任何内容。
这种异常锁定行为的发生是因为您有unindexed foreign key。
如果您创建索引create index t2_idx on t2(col1);
,则会收到ORA-02292
错误而非锁定。
答案 1 :(得分:0)
锁定来自您的行:insert into t2 values('1','0');
当您从会话2中的t1删除时,锁定不会发生。
想一想。在会话1中插入此行后,t2.col1的引用将返回t1.col1。此时外键已经过验证,Oracle知道t1中存在'1'。如果会话2可以从t1删除该行,那么会话2将在t2中具有对t1具有无效引用的未提交行,这没有任何意义。