ITPub博客

首页 > 数据库 > Oracle > ORACLE DML语句锁机制导致事务等待示例

ORACLE DML语句锁机制导致事务等待示例

Oracle 作者:dayong2015 时间:2014-09-22 17:15:11 0 删除 编辑
UPDATE产生锁示例
session 1:

SQL> conn dayonger/dayonger;
Connected.
SQL> create table test(id number primary key,name varchar2(10));    --创建测试表
Table created.
SQL> conn / as sysdba
Connected.
SQL> select sid from v$mystat where rownum=1;      
       SID
----------
       131
SQL> conn dayonger/dayonger;
Connected.
SQL> insert into test values(1,'dayonger');      --插入测试数据
1 row created.
SQL> insert into test values(2,'xiaoru');
1 row created.
SQL> commit;
Commit complete.
SQL> update test set name='eryonger' where id=2;     --update修改一行数据,不提交该事务
1 row updated.
session 2:
SQL> select sid from v$mystat where rownum=1;
       SID
----------
       147
SQL> update dayonger.test set name='madaha' where id=2;         --由于session 1对该行数据修改未结束,该事务将等待
session 3:
SQL> select sid from v$mystat where rownum=1;
       SID
----------
       148
SQL> select sid,type,id1,id2,lmode,request,block from v$lock where sid in (131,147) order by 1,2;

       SID TY        ID1        ID2      LMODE    REQUEST      BLOCK
---------- -- ---------- ---------- ---------- ---------- ----------
       131 TM      52647          0          3          0          2
       131 TX      65580        410          6          0          1
       147 TM      52647          0          3          0          2
       147 TX      65580        410          0          6          0
SQL> select sid,event from v$session_wait where sid in (131,147);

       SID EVENT
---------- ----------------------------------------------------------------
       131 SQL*Net message from client
       147 enq: TX - row lock contention
批注:
v$lock的lmode和request相应数值的含义是:

TM是一个表级锁(段锁),表示此表的记录在修改时,不允许对表进行DDL操作;
TX是一个行级锁(事务锁),表示不允许对表修改的记录进行DML操作;
当TY=TM and ID2=0时,ID1的值为此表(段)的object_id;
当TY=TX and ID2<>0时,ID1+ID2构成了这个事务在回滚段中的位置;
LMODE=3表示一个行级排它锁,LMODE=6表级的排他锁;
REQUEST=6 表示当前会话正待等待一个LMODE=6 的锁,表明这个会话正在被阻塞;
block=1是表示这个会话正在阻塞其它会话;
DELETE产生锁示例
session1:
SQL>set sqlprompt '&window>'           
Enter value for window: session1
session1>select sid from v$mystat where rownum=1;
       SID
----------
       148
session1>select * from dayonger.test;
        ID NAME
---------- ----------
         1 dayonger
         2 xiaoru
session1>delete from dayonger.test where id=2;      --执行delete,该语句不提交
1 row deleted.
session2:
session2>select sid from v$mystat where rownum=1;
       SID
----------
       131
SQL> set sqlprompt '&window>'
Enter value for window: session2
session2>delete from dayonger.test where id=2;   --此时删除同行数据时产生等待
session3:
session3>select sid,type,id1,id2,lmode,request,block from v$lock
  2  where sid in(131,148) order by 1,2;

       SID TY        ID1        ID2      LMODE    REQUEST      BLOCK
---------- -- ---------- ---------- ---------- ---------- ----------
       131 TM      52647          0          3          0          2
       131 TX     393249        411          0          6          0
       148 TM      52647          0          3          0          2
       148 TX     393249        411          6          0          1
session3>select sid,event from v$session_wait where sid in(131,148);

       SID EVENT
---------- ----------------------------------------------------------------
       131 enq: TX - row lock contention
       148 SQL*Net message from client
批注:
TM是一个表级锁(段锁),表示此表的记录在修改时,不允许对表进行DDL操作;
TX是一个行级锁(事务锁),表示不允许对表修改的记录进行DML操作;
当TY=TM and ID2=0时,ID1的值为此表(段)的object_id;
当TY=TX and ID2<>0时,ID1+ID2构成了这个事务在回滚段中的位置;
LMODE=3表示一个行级排它锁,LMODE=6表级的排他锁;
REQUEST=6 表示当前会话正待等待一个LMODE=6 的锁,表明这个会话正在被阻塞;
block=1是表示这个会话正在阻塞其它会话;
INSERT产生锁示例
session1:
session1>select sid from v$mystat where rownum=1;
       SID
----------
       148
session1>insert into dayonger.test values (3,'demaxiya');      --插入数据不提交
1 row created.
session2:
session1>select sid from v$mystat where rownum=1;
       SID
----------
       131
session2>insert into dayonger.test values (3,'sameID');    --插入相同的ID号,该表中ID为主键,事务将等待
session3:
session3>select sid,type,id1,id2,lmode,request,block from v$lock
  2  where sid in(131,148) order by 1,2;

       SID TY        ID1        ID2      LMODE    REQUEST      BLOCK
---------- -- ---------- ---------- ---------- ---------- ----------
       131 TM      52647          0          3          0          2
       131 TX     655390        424          6          0          2
       131 TX     589846        428          0          4          0
       148 TM      52647          0          3          0          2
       148 TX     589846        428          6          0          1

session3>select sid,event from v$session_wait where sid in(131,148);

       SID EVENT
---------- ----------------------------------------------------------------
       131 enq: TX - row lock contention
       148 SQL*Net message from client
批注:
这里和update产生锁的情况不一样的是,session2在持有一个LMODE=6的排他锁和等待一个LMODE=4的锁。
因插入的并不是同一条记录,session2插入时的记录没被阻塞,而是对表的数据块头修改的阻塞,所以会话在请求一个LMODE=4的锁。
SELECT ... FOR UPDATE产生锁示例
session1:
session1>select sid from v$mystat where rownum=1;
       SID
----------
       148
session1>select * from dayonger.test for update;

        ID NAME
---------- ----------
         3 demaxiya
         1 dayonger
         2 xiaoru
session2:
session2>select * from dayonger.test;

        ID NAME
---------- ----------
         3 demaxiya
         1 dayonger
         2 xiaoru
session2>update dayonger.test set name='douzhanshenghuo' where id=3;
session3:

session3>select sid,type,id1,id2,lmode,request,block from v$lock
  2  where sid in(131,148) order by 1,2;

       SID TY        ID1        ID2      LMODE    REQUEST      BLOCK
---------- -- ---------- ---------- ---------- ---------- ----------
       131 TM      52647          0          3          0          2
       131 TX     393236        412          0          6          0
       148 TM      52647          0          3          0          2
       148 TX     393236        412          6          0          1

session3>select sid,event from v$session_wait where sid in(131,148);

       SID EVENT
---------- ----------------------------------------------------------------
       131 enq: TX - row lock contention
       148 SQL*Net message from client
补充:可以使用如下语句杀掉导致等待事件的会话
session3>alter system kill session '148,131';
System altered.
session3>select sid,type,id1,id2,lmode,request,block from v$lock
  2  where sid in(131,148) order by 1,2;
no rows selected

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/29634949/viewspace-1277294/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2014-04-29

  • 博文量
    78
  • 访问量
    790445