锁定父表中的删除而不是错误

时间:2012-11-15 00:29:59

标签: oracle

我有Oracle Database 11g企业版11.2.0.1.0版。 我有父表t1和t2与外键引用t1(col1)。 我想知道锁定的原因是什么? 请检查我做了什么...

会话1

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.

会话2

SQL> delete from t1;    -- Lock happens here!!!

会话1

SQL> commit;
Commit complete.        

会话2

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

有人能解释我为什么会这样吗?

2 个答案:

答案 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具有无效引用的未提交行,这没有任何意义。