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