您的位置:首页 > 其它

模拟insert,update和delete造成阻塞的示例

2013-10-28 09:37 309 查看
会话1SID

BYS@dg2>select distinct sid from v$mystat;

       SID

----------

        17

会话2SID

BYS@dg2>select distinct sid from v$mystat;

       SID

----------

        49

insert造成阻塞的示例

在会话1向表T插入一条数据值1,因为插入数据所在字段有主键约束。

此时会话1不提交或回滚插入操作时,在会话2进行同样的向表T插入一条数据值1时被发生阻塞,语句无法执行。

此时再打开一个会话,可以从v$lock视图中查询出有锁的表及所在会话ID。

会话1:

BYS@dg2>create table t(x number primary key);---新建表,设置主键

Table created.

BYS@dg2>insert into t values(1);    --插入数据不提交

1 row created.

BYS@dg2>

会话2:此时执行插入相同数值时被阻塞----hang住。

BYS@dg2>insert into t values(1);

如果会话1提交,阻塞中止,此时会话2语句执行并报错,提示违反了主键的一致性约束

BYS@dg2>insert into t values(1);

insert into t values(1)

*

ERROR at line 1:

ORA-00001: unique constraint (BYS.SYS_C0011300) violated

会话3:

SID:会话id号

TYPE:锁的类型

ID1:会话操作对象的id号

ID2:ID1+ID2 定位回滚段上的一个地址(即修改之前数据镜像地址),由于138和156会话是一样的说明指向的是同一个地址,换句话说操作的是同一行数据

LMODE:锁模式,不同的数字代表不同的锁模式  例如  0 现在没有申请到锁   3  共享锁模式(段级共享锁)   6  排他锁模式   锁的级别越高限制越多

REQUEST:目前会话没有锁,正在申请的锁模式  例如  0 没有正在申请的锁,说明已经有锁了   6  现在正在申请6号锁,目前因为没有才申请

BLOCK:当前正在阻塞几个会话  例如  1  当前正在阻塞一个会话  2  当前正在阻塞两个会话

锁的实质:是维护一个事务完整性的,锁的信息是数据块的一个属性,是物理的,并不是逻辑上属于某个表或者某几行的。

BYS@dg2>select sid,type,id1,id2,lmode,request,block from v$lock where type in('TM','TX');

       SID TY        ID1        ID2      LMODE    REQUEST      BLOCK

---------- -- ---------- ---------- ---------- ---------- ----------

        49 TX      65562        824          0          4          0    --插入的修改值相同才被阻塞,锁级别是4

        49 TM      75052          0          3          0          0

        17 TM      75052          0          3          0          0

        49 TX     327706       1041          6          0          0    --49号会话插入第二条记录未被阻塞

        17 TX      65562        824          6          0          1 -----正在阻塞一个会话

BYS@dg2>select sid,event from v$session_wait where sid in (49,17);

       SID EVENT

---------- ----------------------------------------------------------------

        17 SQL*Net message from client

        49 enq: TX - row lock contention

insert时v$lock视图里面多了一个TX锁(就是最后一行)。

insert和update delete操作的不同,后两者都是对同一条记录的修改权争用产生阻塞(这里不涉及修改值的问题),

而insert操作实际上插入了2条不同的记录,由于这2条不同的记录的修改值一样违反了主键约束从而产生阻塞,实际是对修改值的相同产生了阻塞。锁的级别为4,这种锁比update的锁级别要低,锁的级别越低限制越少。

#####################################################

update造成阻塞的示例

会话1:

BYS@dg2>update t set x=2 where x=1;

1 row updated.

BYS@dg2>

会话二:

BYS@dg2>update t set x=3 where x=1;

会话3

BYS@dg2>select sid,type,id1,id2,lmode,request,block from v$lock where type in('TM','TX');

       SID TY        ID1        ID2      LMODE    REQUEST      BLOCK

---------- -- ---------- ---------- ---------- ---------- ----------

        49 TX     196624       1041          0          6          0

        49 TM      75052          0          3          0          0

        17 TM      75052          0          3          0          0

        17 TX     196624       1041          6          0          1

BYS@dg2>select sid,event from v$session_wait where sid in (49,17);

       SID EVENT

---------- ----------------------------------------------------------------

        17 SQL*Net message from client

        49 enq: TX - row lock contention

BYS@dg2>col object_name for a20

BYS@dg2>select object_name from dba_objects where object_id=75052;

OBJECT_NAME

--------------------

T

说明 :17会话在T表加了TM TX锁。TM锁模式为3--共享锁 TX锁模式为6--排它锁。

目前TX锁正在阻塞一个会话-49  可以在49的行看到它在请求一个模式为6的锁。

49会话是当前被阻塞的会话,它操作的对象也是T表(从ID1看)。

TM锁模式也为3(共享锁是有几个会话就可以创建几个共享锁,同时存在).

此时它正在申请17会话所持有的模式为6的锁(操作同一行数据)。

delete造成阻塞的示例

会话1:

BYS@dg2>delete from t;  17会话在删除表内记录-只有一条。未提交,加了TM TX锁

1 row deleted.

会话2:

BYS@dg2>delete from t;  此时在49会话也进行删除表内记录,hang住

会话3:

BYS@dg2>select sid,type,id1,id2,lmode,request,block from v$lock where type in('TM','TX');

       SID TY        ID1        ID2      LMODE    REQUEST      BLOCK

---------- -- ---------- ---------- ---------- ---------- ----------

        49 TX     262145        912          0          6          0 --被阻塞了正在申请一个模式6的锁

        49 TM      75052          0          3          0          0

        17 TM      75052          0          3          0          0

        17 TX     262145        912          6          0          1    持有模式6锁,阻塞一个会话

BYS@dg2>select sid,event from v$session_wait where sid in (49,17);

       SID EVENT

---------- ----------------------------------------------------------------

        17 SQL*Net message from client

        49 enq: TX - row lock contention

49会话因TX锁争用导致hang,enq=enqueues队列锁

#####################

select...for update 锁阻塞  这是一种对结果集修改的保护机制

场景:一次性修改多条记录的时候会用到这个命令,起到锁定结果集的效果,这也是结果集修改引起的阻塞

会话1:

BYS@dg2>select * from t where x=2 for update;   对查询出的结果集进行独占,此时不允许其他会话进行修改

         X

----------

         2

会话2:

BYS@dg2>select * from t where x=2 for update;

会话3:

BYS@dg2>select sid,type,id1,id2,lmode,request,block from v$lock where type in('TM','TX');

       SID TY        ID1        ID2      LMODE    REQUEST      BLOCK

---------- -- ---------- ---------- ---------- ---------- ----------

        49 TX     589852       1023          0          6          0

        49 TM      75052          0          3          0          0

        17 TM      75052          0          3          0          0

        17 TX     589852       1023          6          0          1

17号会话阻塞49号会话。这种方法可以一次锁定多行记录。一个表上只能有一个6号锁。

BYS@dg2>select sid,event from v$session_wait where sid in (49,17);

       SID EVENT

---------- ----------------------------------------------------------------

        17 SQL*Net message from client

        49 enq: TX - row lock contention
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: