联系:QQ(5163721)
标题:insert 的enq: TM – contention的情况-2 —–只有主键约束无子表的情况
作者:Lunar©版权所有[文章允许转载,但必须以链接方式注明源地址,否则追究法律责任.]
insert 的enq: TM – contention的情况-1 —–对有主外键关系的表的操作
insert 的enq: TM – contention的情况-2 —–只有主键约束无子表的情况
####################################################################################
总结2 :
1,当存在pk时,无论有没有子表,对存在pk的表来说,无论有没有子表,update pk的操作会同时阻塞对该表做insert操作中那些pk跟update语句更改前、后两个值相关的会话。
2,当子表无事务时,我下面的简单的测试情况下(其他复杂情况没有测试)跟上述第一点结果相同
####################################################################################
测试6: 在测试5的基础上,测试一下子表无事务的情况下,对父表的update是如何影响父表的delete和insert的
首先,我们在Session 4(SID 116)对做commit,此时session 2(SID 220)会自动解锁,并报出来应有的违反约束的错误ORA-02292:
Session 4:
SQL> SELECT sid FROM v$session WHERE audsid = userenv('SESSIONID'); SID ---------- 116 SQL> INSERT INTO DEPT VALUES (2,'LUNAR'); 1 row created. SQL> commit; Commit complete. SQL> Session 2: SQL> SELECT sid FROM v$session WHERE audsid = userenv('SESSIONID'); SID ---------- 220 SQL> delete from dept where deptno = 1; delete from dept where deptno = 1 * ERROR at line 1: ORA-02292: integrity constraint (LUNAR.FK_DEPTNO) violated - child record found SQL>
现在,我们把所有的会话都做commit或者rollback,然后观察对父表的updae会不会对父表的其他DML操作有影响:
Session 2(SID 220):
SQL> select * from dept; DEPTNO DNAME ---------- ---------- 1 COSTCENTER 5 baobao 2 LUNAR SQL> update dept set deptno =3 WHERE DEPTNO=2; 1 row updated. SQL> Session 4(SID 116): SQL> DELETE FROM DEPT WHERE DEPTNO=1; DELETE FROM DEPT WHERE DEPTNO=1 * ERROR at line 1: ORA-02292: integrity constraint (LUNAR.FK_DEPTNO) violated - child record found SQL> Session 5(SID 222): SQL> INSERT INTO DEPT VALUES (3,'BAOBAO'); ....HANG..... Session 3观察: SID TY ID1 ID2 LMODE REQUEST BLOCK ---------- -- ---------- ---------- ---------- ---------- ---------- 220 TM 1062788 0 3 0 0 220 TX 1310742 42714 6 0 1 222 TM 1062788 0 3 0 0 222 TM 1062790 0 3 0 0 222 TX 1310742 42714 0 4 0 222 TX 1507340 34195 6 0 0 SPID SID SERIAL# STATUS ------------------------ ---------- ---------- -------- SQL_TEXT -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- SQL_ID EVENT STATUS ------------- ---------------------------------------------------------------- -------- 12766 222 49879 ACTIVE INSERT INTO DEPT VALUES (3,'BAOBAO') 9pmgcjs6qd7sa enq: TX - row lock contention ACTIVE
这里看见session 4对父表的delete不受session 2在父表的update的影响,而session 5对父表的insert 会被session 2在父表的update阻塞
被阻塞的对父表的insert操作等待事件为:enq: TX – row lock contention
在测试一次:
把上面所有会话都commit或者rollback,然后:
Session 2(SID 220):
SQL> select * from dept; DEPTNO DNAME ---------- ---------- 1 COSTCENTER 5 baobao 2 LUNAR SQL> update dept set deptno =3 WHERE DEPTNO=2; 1 row updated. SQL> rollback; Rollback complete. SQL> SELECT sid FROM v$session WHERE audsid = userenv('SESSIONID'); SID ---------- 220 SQL> SQL> update dept set deptno =3 WHERE DEPTNO=2; ---------注意这里,deptno被更新为3 1 row updated. SQL> Session 4(SID 116): SQL> SELECT sid FROM v$session WHERE audsid = userenv('SESSIONID'); SID ---------- 116 SQL> INSERT INTO DEPT VALUES (6,'BAOBAO'); 1 row created. SQL> INSERT INTO DEPT VALUES (3,'BAOBAO'); -----------注意这里,只有插入deptno为3时才会被阻塞 ..... HANG.....
这里我们看到,对父表的update阻塞了对其他会话对父表insert时pk的值=updae父表的pk的值的会话。
这个我们可以再做一个测试:
测试7,新建两个表,一个有pk,一个无pk,然后做同样的update和insert操作:
无pk的表:
CREATE TABLE LUNAR1 ( deptno NUMBER , dname VARCHAR2(10) ); insert into LUNAR1 values (1, 'LUNAR'); insert into LUNAR1 values (5, 'BAOBAO'); insert into LUNAR1 values (2, 'HAOBAOBAO'); commit; sessin 1: update LUNAR2 set deptno =3 WHERE DEPTNO=2; ----注意这里,deptno被更新为3 session 2: INSERT INTO LUNAR1 VALUES (7,'DABAOBAO'); INSERT INTO LUNAR1 VALUES (3,'DABAOBAO'); -----注意这里,插入了deptno为3的记录
这测试不会有任何问题。
现在我们改为带有pk的表:
CREATE TABLE LUNAR2 ( deptno NUMBER CONSTRAINT pk_LUNAR PRIMARY KEY, dname VARCHAR2(10) ); insert into LUNAR2 values (1, 'LUNAR'); insert into LUNAR2 values (5, 'BAOBAO'); insert into LUNAR2 values (2, 'HAOBAOBAO'); commit;
SESSION 1:
SQL> update LUNAR2 set deptno =3 WHERE DEPTNO=2; ----注意这里,deptno=2的记录被更新为deptno=3 1 row updated. SQL> SESSION 2: SQL> INSERT INTO LUNAR2 VALUES (7,'DABAOBAO'); 1 row created. Elapsed: 00:00:00.00 SQL> INSERT INTO LUNAR2 VALUES (3,'DABAOBAO'); -----注意这里,只有deptno为3的插入被阻塞 ....HANG..... 取消掉,改为插入deptno=2的试试看: SQL> INSERT INTO LUNAR2 VALUES (3,'DABAOBAO'); ^Z^CINSERT INTO LUNAR2 VALUES (3,'DABAOBAO') * ERROR at line 1: ORA-01013: user requested cancel of current operation Elapsed: 00:09:31.33 SQL> INSERT INTO LUNAR2 VALUES (2,'DABAOBAO'); -----注意这里,只有deptno为2的插入被阻塞 ....HANG.....
也就是说,对存在pk的表来说,无论有没有子表,update pk的操作会同时阻塞对该表做insert操作中那些pk跟update语句更改前、后两个值相关的会话
比如update LUNAR2 set deptno =3 WHERE DEPTNO=2,就会阻塞所有insert deptno=2和deptno=3的会话
——未完,待续—