怎么验证LOCK请求的FIFO机制

77次阅读
没有评论

共计 6905 个字符,预计需要花费 18 分钟才能阅读完成。

本篇内容主要讲解“怎么验证 LOCK 请求的 FIFO 机制”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让丸趣 TV 小编来带大家学习“怎么验证 LOCK 请求的 FIFO 机制”吧!

在多并发的会话场景中,需要先获取资源的 X 锁定才能对该资源进行修改。与此同时,当其他会话也同样请求修改该资源时,则必须按照先进先服务的方式(FIFO)进入请求队列排队等候。以下实验可以验证这一机制。

创建表

create table t1(c1
number, c2 number);

insert into t1
values(101, 5000);

commit;

三个会话按照先后顺序试图更新数据,会话的 SID 可以通过以下查询获取

select
userenv(sid) from dual;

Session1(SID:129)

update t1 set c2=6000
where c1=101;

Session2(SID:135)

update t1 set c2=7000
where c1=101;

Session3(SID:138)

update t1 set c2=8000
where c1=101;

可以看到,Session1 执行更新后因为没有提交,Session2 和 Session3 都在等待。此时查询事务信息,显示有一个事务

select xid, addr,
ses_addr, xidusn, xidslot, xidsqn, ubafil, ubablk, ubasqn, ubarec, status,
start_time from v$transaction;

XID  ADDR  SES_ADDR  XIDUSN  XIDSLOT 
XIDSQN  UBAFIL  UBABLK 
UBASQN  UBAREC STATUS  START_TIME

—————-
—————- —————- ———- ———- ———- ———-
———- ———- ———- —————- ——————–

0100060090020000
000007FF49D24CA8 000007FF4C78B2A0 
1  6  656  3  717  145  35 ACTIVE  10/04/17 11:44:47

查看锁定信息,存在事务回滚段号 XIDUSN 的会话表示正在执行的事务,129 会话优先获取锁,XIDUSN 为 0 则表示会话被锁,处于等待状态,LOCKED_MODE 为 3 表示行独占锁

col oracle_username for
a15

select * from
v$locked_object;

  XIDUSN 
XIDSLOT  XIDSQN  OBJECT_ID SESSION_ID ORACLE_USERNAME
OS_USER_NAME 
PROCESS 
LOCKED_MODE

———- ———-
———- ———- ———- ————— ——————————
———————— ———–

  1  6  656 
73449  129 SYS  VM-ORA11G-1\Administrator  3136:1796  3

  0  0  0 
73449  135 SYS  VM-ORA11G-1\Administrator  2932:2184  3

  0  0  0 
73449  138 SYS  VM-ORA11G-1\Administrator  3820:2100  3

再看锁队列,129 会话因为已经获取到锁,所以只有 AE 会话锁,没有 TX 锁请求,CTIME 为请求时间,135 会话先于 138 会话,REQUEST 大于 0 表示当前会话被阻塞,其它会话以对应的模式占有锁

select * from
v$enqueue_lock where sid in (129, 135, 138);

ADDR  KADDR  SID TY  ID1  ID2 
LMODE  REQUEST  CTIME 
BLOCK

—————-
—————- ———- — ———- ———- ———- ———-
———- ———-

000007FF4CC56968
000007FF4CC569C0  129 AE  100  0  4  0  6898  0

000007FF4CC56BD8
000007FF4CC56C30  135 AE  100  0  4  0  3183  0

000007FF4CC56E48
000007FF4CC56EA0  135 TX  65542  656  0  6  3152  1

000007FF4CC56F18
000007FF4CC56F70  138 AE  100  0  4  0  3140  0

000007FF4CC57000
000007FF4CC57058  138 TX  65542  656  0  6  3106  0

锁类型 TYPE 列的定义:TM- 表级锁,TX- 事务锁,MR-Media Recovery(每个文件一个),AE- 会话锁(每个会话一个),UL- 用户定义的锁类型

锁模式 LMODE 列的定义:0-none;1- 空(NULL);2- 行共享(RS);3- 行独占(RX);4- 共享锁(S);5- 共享行独占(SRX);6- 独占锁(X)

dump 等待队列,可见 129 会话 que 为 own 表示正在持有锁,135 会话和 138 会话 que 为 wat 表示正在锁请求等待

oradebug setmypid

oradebug tracefile_name

oradebug dump enqueues 8

000007FF4CD05DC0
TX-00010006-00000290 U  0  0 
0  0  0  1
40 [4cd25530,4cd25530]

  [49d24d30,49d24d30]
[4cd05df0,4cd05df0] [4cc56eb0,4cc57068]

  lock 
que owner  session  hold wait ser link

 
———————————————————————-

  000007FF49D24D20 OWN 000007FF4C78B2A0
000007FF4C78B2A0 (129)  X NLCK  73 [4cd05dd0,4cd05dd0]

  000007FF4CC56EA0 WAT 000007FF4C779C00
000007FF4C779C00 (135) NLCK  X 1468
[4cc57068,4cd05de0]

  000007FF4CC57058 WAT 000007FF4C7710B0
000007FF4C7710B0 (138) NLCK  X 1191
[4cd05de0,4cc56eb0]

对照验证,将 Session1 提交,查看事务,新的事务在执行

select xid, addr,
ses_addr, xidusn, xidslot, xidsqn, ubafil, ubablk, ubasqn, ubarec, status,
start_time from v$transaction;

XID  ADDR  SES_ADDR  XIDUSN  XIDSLOT 
XIDSQN  UBAFIL  UBABLK 
UBASQN  UBAREC STATUS  START_TIME

—————-
—————- —————- ———- ———- ———- ———-
———- ———- ———- —————- ——————–

050006005D030000
000007FF49D256A8 000007FF4C779C00 
5  6  861  3  536  187  14 ACTIVE  10/04/17 11:45:36

查看锁定对象,129 会话的锁已释放,所以无记录,135 会话正在执行事务而获得锁,138 会话则继续等待

col oracle_username for
a15

select * from
v$locked_object;

  XIDUSN 
XIDSLOT  XIDSQN  OBJECT_ID SESSION_ID ORACLE_USERNAME
OS_USER_NAME 
PROCESS 
LOCKED_MODE

———- ———-
———- ———- ———- ————— ——————————
———————— ———–

  5  6  861 
73449  135 SYS  VM-ORA11G-1\Administrator  2932:2184  3

  0  0  0 
73449  138 SYS  VM-ORA11G-1\Administrator  3820:2100  3

查看请求队列,129 会话和 135 会话都已经获取了请求,138 会话仍有 TX 锁请求

select * from
v$enqueue_lock where sid in (129, 135, 138);

ADDR  KADDR  SID TYPE  ID1  ID2 
LMODE  REQUEST  CTIME 
BLOCK

—————-
—————- ———- —- ———- ———- ———- ———-
———- ———-

000007FF4CC56968
000007FF4CC569C0  129 AE  100  0  4  0 
21793  0

000007FF4CC56BD8
000007FF4CC56C30  135 AE  100  0  4  0 
18078  0

000007FF4CC56E48
000007FF4CC56EA0  138 TX  327686  861  0  6  674  0

000007FF4CC56F18
000007FF4CC56F70  138 AE  100  0  4  0 
18035  0

dump 等待队列,可见 135 会话 que 为 own 表示正在持有锁,138 会话 que 为 wat 表示正在锁请求等待

oradebug setmypid

oradebug tracefile_name

oradebug dump enqueues 8

000007FF4CD07F98
TX-00050006-0000035d U  0  0 
0  0  0  1
40 [4cd25bc0,4cd25bc0]

  [49d25730,49d25730]
[4cd07fc8,4cd07fc8] [4cc56eb0,4cc56eb0]

  lock 
que owner  session  hold wait ser link

 
———————————————————————-

  000007FF49D25720 OWN 000007FF4C779C00
000007FF4C779C00 (135)  X NLCK 1468
[4cd07fa8,4cd07fa8]

  000007FF4CC56EA0 WAT 000007FF4C7710B0
000007FF4C7710B0 (138) NLCK  X 1191
[4cd07fb8,4cd07fb8]

对照验证,将 Session2 提交,查看事务,又一新的事务在执行

select xid, addr,
ses_addr, xidusn, xidslot, xidsqn, ubafil, ubablk, ubasqn, ubarec, status,
start_time from v$transaction;

XID  ADDR  SES_ADDR  XIDUSN  XIDSLOT 
XIDSQN  UBAFIL  UBABLK 
UBASQN  UBAREC STATUS  START_TIME

—————-
—————- —————- ———- ———- ———- ———-
———- ———- ———- —————- ——————–

09000D003D030000
000007FF49CC9678 000007FF4C7710B0 
9  13  829  3  2477  184  28 ACTIVE  10/04/17 11:46:22

查看锁定对象,135 会话的锁也已释放,138 会话正在执行事务而获得锁,没有会话在等待了

col oracle_username for
a15

select * from
v$locked_object;

  XIDUSN 
XIDSLOT  XIDSQN  OBJECT_ID SESSION_ID ORACLE_USERNAME
OS_USER_NAME 
PROCESS 
LOCKED_MODE

———- ———-
———- ———- ———- ————— ——————————
———————— ———–

  9  13  829 
73449  138 SYS  VM-ORA11G-1\Administrator  3820:2100  3

查看请求队列,已经没有 TX 锁请求

select * from
v$enqueue_lock where sid in (129, 135, 138);

ADDR  KADDR  SID TY  ID1  ID2 
LMODE  REQUEST  CTIME 
BLOCK

—————-
—————- ———- — ———- ———- ———- ———-
———- ———-

000007FF4CC56968
000007FF4CC569C0  129 AE  100  0  4  0 
24483  0

000007FF4CC56BD8
000007FF4CC56C30  135 AE  100  0  4  0 
20768  0

000007FF4CC56F18
000007FF4CC56F70  138 AE  100  0  4  0 
20725  0

dump 等待队列,只有 138 会话的记录了,并且 que 为 own 表示已经拥有

oradebug setmypid

oradebug tracefile_name

oradebug dump enqueues 8

000007FF4CD00378
TX-0009000d-0000033d U  0  0 
0  0  0  1
40 [4cd23730,4cd23730]

  [49cc9700,49cc9700]
[4cd003a8,4cd003a8] [4cd00398,4cd00398]

  lock 
que owner  session  hold wait ser link

 
———————————————————————-

  000007FF49CC96F0 OWN 000007FF4C7710B0
000007FF4C7710B0 (138)  X NLCK 1191
[4cd00388,4cd00388]

如果此时关闭已经提交了的 Session1 和 Session2 会话,则请求队列中不会再有 129 和 135 会话的 AE 锁记录,在 Oracle 11g 中 AE 锁是每个会话都会有一个的,对于 Oracle
10g 则不存在 AE 会话锁

select * from
v$enqueue_lock where sid in (129, 135, 138);

ADDR  KADDR  SID TY  ID1  ID2 
LMODE  REQUEST  CTIME 
BLOCK

—————-
—————- ———- — ———- ———- ———- ———-
———- ———-

000007FF4CC56F18
000007FF4CC56F70  138 AE  100  0  4  0 
21120  0

由此,我们通过实验来验证了锁队列的 FIFO 机制,遵循先请求先服务的原则。

最后,清理实验用表

drop table t1 purge;

到此,相信大家对“怎么验证 LOCK 请求的 FIFO 机制”有了更深的了解,不妨来实际操作一番吧!这里是丸趣 TV 网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-08-01发表,共计6905字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)