共計 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 網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!