今天參考了一些文檔作了以下一點實驗記錄了整個過程留個記錄吧
一 插入時鎖的情況
打開一個命令行窗口用sqlplus登陸到oracle
c[oracle@qatest ~]$ sqlplus fortune/fortune
SQL*Plus: Release Production on Sun May ::
Copyright (c) Oracle All Rights Reserved
Oracle Database g Enterprise Edition Release Production
With the Partitioning OLAP Data Mining and Real Application Testing options
創建一個測試表
SQL>
SQL> create table test (a numbera char());
create table test (a numbera char())
SQL> desc test
Name Null? Type
A NUMBER
A CHAR()
插入幾條測試數據
SQL> insert into test values ();
row created
SQL> select * from test;
A A
SQL> insert into test values ();
row created
SQL> commit;
SQL> select * from test;
A A
SQL> insert into test values ();
row created
SQL> insert into test values ();
row created
用sys用戶可以查看到當前的sid號碼:
SQL> select sid username from v$session where username=FORTUNE;
SID USERNAME
FORTUNE
用sys用戶登進去查看當前sid所占有的鎖及類型:(在沒有commit之前所占有的鎖)
SQL> select sidtypelmoderequest from v$lock where sid in() order by sid;
SID TY LMODE REQUEST
TX
TM
SQL> commit;
commit之後再查一下sid為的進行的鎖的情況:commit之後就不占用鎖了
SQL> select sidtypelmoderequest from v$lock where sid in() order by sid;
no rows selected
重新打開一個命令行窗口使用fortune用戶登入第二的進程
[oracle@qatest ~]$ sqlplus fortune/fortune
SQL*Plus: Release Production on Sun May ::
Copyright (c) Oracle All Rights Reserved
Connected to:
Oracle Database g Enterprise Edition Release Production
With the Partitioning OLAP Data Mining and Real Application Testing options
SQL>
SQL>
用sys用戶可以看到這兩個進行的SID號
SQL> select sid username from v$session where username=FORTUNE;
SID USERNAME
FORTUNE
FORTUNE
在第一個窗口執行以下插入: (SID 為) 不要commit
SQL> insert into test values ();
row created
在第二個窗口執行以下插入:(SID 為)同樣也不要commit:
SQL>
SQL> insert into test values ();
row created
這時再用sys用戶查看fortune 用戶所占有的sid總共占有的鎖及類型:(在沒有commit之前所占有的鎖)
SQL> select sid typelmoderequest from v$lock where sid in() order by sid;
SID TY LMODE REQUEST
TX
TM
TX
TM
這時在窗口一執行commit:
SQL> commit;
Commit complete
這時再用sys用戶查看fortune 用戶所占有的鎖及類型:
SQL> select sid typelmoderequest from v$lock where sid in() order by sid;
SID TY LMODE REQUEST
TX
TM
可以看到sid為的鎖已經釋放了只有sid 所占有的鎖了
這時在窗口二執行commit:
SQL> commit;
Commit complete
這時再用sys用戶查看fortune 用戶所占有的鎖及類型:
SQL> select sid typelmoderequest from v$lock where sid in() order by sid;
no rows selected
SQL> select * from test;
A A
發現沒有鎖了記錄已經添加成功了
二 Update 時鎖的占用情況:
在窗口一執行一個update:(不要commit)
SQL> update test set a= where a=;
row updated
同樣在窗口二也執行一個update更新同一行數據: (不要commit)
SQL> update test set a= where a=;
row updated
這時可以看到這個窗口已經停止反應了
這時用sys用戶查看fortune用戶的鎖情況如下:
SQL> select sid typelmoderequest from v$lock where sid in() order by sid;
SID TY LMODE REQUEST
TM
TX
TM
TX
發現的TX類型的鎖裡request 為是在等待另外一個鎖
這時用sys查看一下sid 對應的系統事件:
SQL> select sidevent from v$session where sid=;
SID EVENT
enq: TX row lock contention
可以看到在等一個row lock的結束
這時在窗口一執行commit:
SQL> commit;
Commit complete
這時在窗口二的update就有反應了
這時再用sys查看一下sid 對應的系統事件:
SQL> select sidevent from v$session where sid=;
SID EVENT
SQL*Net message from client
在這可以看到等待結束了
SQL> select sid typelmoderequest from v$lock where sid in() order by sid;
SID TY LMODE REQUEST
TX
TM
以上可以看到sid 占有的鎖已經都釋放了
SQL> select * from test;
A A
在這也可以看到a=這一行的A值已經被更新為了
這時再到窗口二執行commit
SQL> commit;
Commit complete
再看鎖的情況發現fortune用戶的鎖都已經釋放了
SQL> select sid typelmoderequest from v$lock where sid in() order by sid;
no rows selected
SQL> select * from test;
A A
在這也可以看到a=這一行的A值已經被更新為了
三 鎖的解除
在窗口一上執行以下更新:
SQL> update test set a= where a=;
row updated
在窗口二執行以下更新:
SQL> update test set a= where a=;
這時和上面一樣可以看到窗口二hang住了沒反應了 我等了半小時還是一樣
這時用sys用戶來查詢一下fortune的鎖情況:
SQL> select sid typelmoderequest from v$lock where sid in() order by sid;
SID TY LMODE REQUEST
TM
TX
TM
TX
可以看到和前面的結果是一樣的sid 在等的一個鎖釋放掉
使用以下語句來查一下鎖的情況:
SQL> select Asid bserial#
decode(Atype
MR Media Recovery
RTRedo Thread
UNUser Name
TX Transaction
TM DML
UL PL/SQL User Lock
DX Distributed Xaction
CF Control File
IS Instance State
FS File Set
IR Instance Recovery
ST Disk Space Transaction
TS Temp Segment
IV Library Cache Invalidation
LS Log Start or Switch
RW Row Wait
SQ Sequence Number
TE Extend Table
TT Temp Table
Unknown) LockType
cobject_name
busername
bosuser
decode(almode None
Null
RowS
RowX
Share
S/RowX
Exclusive Unknown) LockMode
BMACHINEDSPID bPROGRAM
from v$lock av$session ball_objects cV$PROCESS D
where asid=bsid and atype in (TMTX)
and cobject_id=aid
AND BPADDR=DADDR
order by username
;
SID SERIAL# LOCKTYPE OBJECT_NAME LOCKMODE MACHINE SPID PROGRAM
DML TEST RowX qatest sqlplus@qatest(TNS VV)
DML TEST RowX qatest sqlplus@qatest(TNS VV)
或者用以下語句也可以:
SQL> select sidserial# from v$session User_Info;
SID SERIAL#
SID SERIAL#
用以下語句來結束窗口一的鎖session
SQL> alter system kill session ;
System altered
這時到窗口二可以看到窗口有反應了update成功了(但還沒有commit)
這時如果在窗口一執行commit可以看到以下報錯
SQL> commit;
commit
*
ERROR at line :
ORA: your session has been killed
這時到窗口二執行commit
SQL> commit;
Commit complete
SQL> select * from test;
A A
可以看到更新已經完成
From:http://tw.wingwit.com/Article/program/Oracle/201311/18483.html