Oracle中锁请求的处理顺序

Oracle中的锁实际对应着三个队列,分别是持有者队列、convertor队列和请求者队列。如果一个会话持有一种模式的锁,这时它又请求另一种模式的锁并且请求的锁与其它持有者已经持有的锁不相容,则这个会话的锁请求进入convertor队列。在锁请求处理过程中convertor队列优先于请求者队列。

以下是测试实例:

1、打开session1:

scott@ora10g: SQL> select sid from v$mystat where rownum=1;

       SID
----------
       143

scott@ora10g: SQL> insert into oib1 values (1,1);

1 row created.

scott@ora10g: SQL> select sid,type,id1,lmode,request,block from v$lock where type='TM';

       SID TY        ID1      LMODE    REQUEST      BLOCK
---------- -- ---------- ---------- ---------- ----------
       143 TM      17112          3          0          0

session1持有测试表RX锁。

2、另开个session2:

scott@ora10g: SQL> select sid from v$mystat where rownum=1;

       SID
----------
       154

scott@ora10g: SQL> lock table oib1 in row share mode;

Table(s) Locked.

session2在测试表上加RS锁,由于RX锁与RS锁相容,session2加锁成功。

scott@ora10g: SQL> select sid,type,id1,lmode,request,block from v$lock where type='TM';

       SID TY        ID1      LMODE    REQUEST      BLOCK
---------- -- ---------- ---------- ---------- ----------
       143 TM      17112          3          0          0
       154 TM      17112          2          0          0

session1持有测试表的RX锁,session2持有RS锁。

3、打开session3:

scott@ora10g: SQL> select sid from v$mystat where rownum=1;

       SID
----------
       142

scott@ora10g: SQL> lock table oib1 in share row exclusive mode;

由于session3要加的锁SRX与RX不相容,session3被阻塞,处于等待状态。

4、回到session1检查加锁情况:

scott@ora10g: SQL> select sid,type,id1,lmode,request,block from v$lock where type='TM';

       SID TY        ID1      LMODE    REQUEST      BLOCK
---------- -- ---------- ---------- ---------- ----------
       143 TM      17112          3          0          1
       154 TM      17112          2          0          1
       142 TM      17112          0          5          0

session1持有RX锁,session2持有RS锁,session3请求SRX锁,被阻塞。

5、回到session2,在测试表上请求S锁:

scott@ora10g: SQL> lock table oib1 in share mode;

由于session2请求的S锁与session1持有的RX锁不相容,session2被阻塞,处于等待状态。

6、回到session1检查加锁情况:

scott@ora10g: SQL> select sid,type,id1,lmode,request,block from v$lock where type='TM';

       SID TY        ID1      LMODE    REQUEST      BLOCK
---------- -- ---------- ---------- ---------- ----------
       143 TM      17112          3          0          1
       154 TM      17112          2          4          1
       142 TM      17112          0          5          0

session1持有RX锁,session2持有RS锁请求S锁被阻塞,session3请求SRX锁被阻塞。


scott@ora10g: SQL> rollback;

Rollback complete.

session1回滚,释放RX锁。

scott@ora10g: SQL> select sid,type,id1,lmode,request,block from v$lock where type='TM';

       SID TY        ID1      LMODE    REQUEST      BLOCK
---------- -- ---------- ---------- ---------- ----------
       154 TM      17112          4          0          1
       142 TM      17112          0          5          0

结果session2取得了S锁,而session3被阻塞。注意是session3先请求的SRX锁,SRX锁与RS锁是相容的,在session1释放掉RX锁之后理应session3获得SRX锁,session2继续持有RS锁,但结果是session2得到了S锁。这就是因为convertor队列优先于请求者队列。session2持有RS锁,在请求S锁时这个请求放在了convertor队列;而session3的请求是放在请求者队列。

原文地址:https://www.cnblogs.com/cqubityj/p/2552287.html