今天参考了一些文档作了以下一点实验记录了整个过程留个记录吧
一 插入时锁的情况
打开一个命令行窗口用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
可以看到更新已经完成