Zack Cao
2010-11-19 17:06:01 UTC
We have encountered an issue where updating a non-pk column on a row
in parent locks insert action on child which references the row just
updated in the parent.
My database(Sql Anywhere 9.0.2 EBF 3951) schema and initial value is:
CREATE TABLE "DBA"."parent" (
"ID" integer NOT NULL DEFAULT autoincrement,
"ColumnOne" integer NOT NULL,
PRIMARY KEY ( "ID" )
);
CREATE TABLE "DBA"."child" (
"ID" integer NOT NULL DEFAULT autoincrement,
"ParentID" integer NOT NULL,
"ColumnOne" integer NOT NULL,
PRIMARY KEY ( "ID" )
);
ALTER TABLE "DBA"."child" ADD NOT NULL FOREIGN KEY
"parent" ( "ParentID" ) REFERENCES "DBA"."parent" ( "ID" );
insert into parent values(1,1);
insert into child values(1,1,1);
commit;
And then: Open Interactive SQL Window 1, isolation level is default 0,
run following but don’t commit yet:
update parent set ColumnOne = 11 where Id = 1;
Open Interactive SQL Window 2, isolation level is default 0, run
following and it will be blocked forever:
insert into child values(default,1,2)
But, if we run Update on Window 2, then it works:
Update chilid set ColumnOne = 11 where Id = 1;
I don’t know why it behaves like that way and keeping transaction
short is not an option for us since Window 1 in production is actually
a Mobilink client downloading large amount of data updating parent
rows, and Window 2 is our application adding data to child. It this
behavior is as designed or not changeable through some DB
configuration, then my application cannot work when mobilink client
has a large download stream.
I’ve tried disable/enable cascade update/delete, check only on a
commit on Fk, none of them seems working.
I then tried Sql Anywhere 11.0.1 EBF2472 with exact same options as
above, same issue. And then I tried:
SET OPTION PUBLIC.allow_snapshot_isolation = 'On';
SET TEMPORARY OPTION isolation_level = 'snapshot' on Window 2
and it still doesn’t work!
Lastly, I tried on Oracle, it just simply worked. I’m puzzled.
Any reply is highly appreciated.
Thanks,
Zack
in parent locks insert action on child which references the row just
updated in the parent.
My database(Sql Anywhere 9.0.2 EBF 3951) schema and initial value is:
CREATE TABLE "DBA"."parent" (
"ID" integer NOT NULL DEFAULT autoincrement,
"ColumnOne" integer NOT NULL,
PRIMARY KEY ( "ID" )
);
CREATE TABLE "DBA"."child" (
"ID" integer NOT NULL DEFAULT autoincrement,
"ParentID" integer NOT NULL,
"ColumnOne" integer NOT NULL,
PRIMARY KEY ( "ID" )
);
ALTER TABLE "DBA"."child" ADD NOT NULL FOREIGN KEY
"parent" ( "ParentID" ) REFERENCES "DBA"."parent" ( "ID" );
insert into parent values(1,1);
insert into child values(1,1,1);
commit;
And then: Open Interactive SQL Window 1, isolation level is default 0,
run following but don’t commit yet:
update parent set ColumnOne = 11 where Id = 1;
Open Interactive SQL Window 2, isolation level is default 0, run
following and it will be blocked forever:
insert into child values(default,1,2)
But, if we run Update on Window 2, then it works:
Update chilid set ColumnOne = 11 where Id = 1;
I don’t know why it behaves like that way and keeping transaction
short is not an option for us since Window 1 in production is actually
a Mobilink client downloading large amount of data updating parent
rows, and Window 2 is our application adding data to child. It this
behavior is as designed or not changeable through some DB
configuration, then my application cannot work when mobilink client
has a large download stream.
I’ve tried disable/enable cascade update/delete, check only on a
commit on Fk, none of them seems working.
I then tried Sql Anywhere 11.0.1 EBF2472 with exact same options as
above, same issue. And then I tried:
SET OPTION PUBLIC.allow_snapshot_isolation = 'On';
SET TEMPORARY OPTION isolation_level = 'snapshot' on Window 2
and it still doesn’t work!
Lastly, I tried on Oracle, it just simply worked. I’m puzzled.
Any reply is highly appreciated.
Thanks,
Zack