Hello Team! :)
I get the "ORA-00060: deadlock detected while waiting for resource" in the following case:
Session1:
--DDL
create table t1(pk number(11) primary key, col1 number(11));
create table t2(pk number(11) primary key, t1_ref_key number(11), col1 number(11),
constraint fk_t2__t1_pk foreign key (t1_ref_key) references t1(pk) on delete cascade);
create table t3(pk number(11) primary key, t1_ref_key number(11), col1 number(11),
constraint fk_t3__t1_pk foreign key (t1_ref_key) references t1(pk) on delete cascade);
create index t2_ref_key on t2(t1_ref_key);
create index t3_ref_key on t3(t1_ref_key);
--DML
insert into t1(pk, col1) values (1, 123);
COMMIT; --commit here
insert into t2(pk, t1_ref_key, col1) values (1, 1, 123);
--no commit yet
Now in Session 2 the following statement is executed:
delete from t1 where pk=1;
--Session 2 waits here
Now again in Session 1:
insert into t3(pk, t1_ref_key, col1) values (1, 1, 123);
--no commit yet
In this moment the Session 2 gets "ORA-00060 deadlock detected ...". Could you please say, why this is happening and how I as a developer can avoid this?
Regards,
Alex
When you insert a row into T2 Oracle blocks deletes to the parent row in T1. Otherwise it can't validate the FK.
When you delete a row from T1 Oracle blocks inserts of potential children of this. Again, this is to ensure it can validate the FK.
So in your example you have:
Session 1 preventing the delete from the parent.
Session 2 preventing the insert into the children.
Deadlock!
How can you avoid this?
Stop deleting from T1! ;)
But I'm guessing that's not an option. You can avoid the deadlock by issuing:
select * from t1 where pk = :x for update;
Before inserting rows into the child tables (T2 & T3).
If the delete starts first, the select will be blocked. When the delete commits, the inserts will go ahead and the FK validation will fail.
If the select for update starts first, the delete will have to wait for this to commit. Once you commit the inserts, the delete will go ahead. The side-effect of this is you'll end up deleting rows you just inserted!