今天参考了一些文档,作了以下一点实验,记录了整个过程,留个记录吧。
一. 插入时锁的情况
1. 打开一个命令行窗口,用sqlplus登陆到oracle.
c[oracle@qatest006 ~]$ sqlplus fortune/fortune
SQL*Plus: Release 10.2.0.4.0 - Production on Sun May 23 19:15:49 2010
Copyright (c) 1982, 2007, Oracle. All Rights Reserved.
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
2. 创建一个测试表.
SQL>
SQL> create table test1 (a1 number,a1 char(10));
create table test1 (a1 number,a1 char(10))
SQL> desc test1
Name Null? Type
----------------------------------------- -------- ----------------------------
A1 NUMBER
A2 CHAR(10)
3. 插入几条测试数据
SQL> insert into test1 values (1,1);
1 row created.
SQL> select * from test1;
A1 A2
---------- ----------
1 1
SQL> insert into test1 values (2,100);
1 row created.
SQL> commit;
SQL> select * from test1;
A1 A2
---------- ----------
1 1
2 100
SQL> insert into test1 values (3,500);
1 row created.
SQL> insert into test1 values (4,867);
1 row created.
4. 用sys用户可以查看到当前的sid号码:
SQL> select sid ,username from v$session where username='FORTUNE';
SID USERNAME
---------- ------------------------------
148 FORTUNE
5. 用sys用户登进去查看当前sid所占有的锁及类型:(在没有commit之前所占有的锁)
SQL> select sid,type,lmode,request from v$lock where sid in(148) order by sid;
SID TY LMODE REQUEST
---------- -- ---------- ----------
148 TX 6 0
148 TM 3 0
SQL> commit;
6. commit之后再查一下sid为148的进行的锁的情况:commit之后就不占用锁了.
SQL> select sid,type,lmode,request from v$lock where sid in(148) order by sid;
no rows selected
7. 重新打开一个命令行窗口,使用fortune用户登入第二的进程
[oracle@qatest006 ~]$ sqlplus fortune/fortune
SQL*Plus: Release 10.2.0.4.0 - Production on Sun May 23 21:12:07 2010
Copyright (c) 1982, 2007, Oracle. All Rights Reserved.
Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL>
SQL>
8. 用sys用户可以看到这两个进行的SID号
SQL> select sid ,username from v$session where username='FORTUNE';
SID USERNAME
---------- ------------------------------
148 FORTUNE
159 FORTUNE
9. 在第一个窗口执行以下插入: (SID 为148) 不要commit
SQL> insert into test1 values (5,888);
1 row created.
10. 在第二个窗口执行以下插入:(SID 为159),同样也不要commit:
SQL>
SQL> insert into test1 values (5,988);
1 row created.
11. 这时再用sys用户查看fortune 用户所占有的sid总共占有的锁及类型:(在没有commit之前所占有的锁)
SQL> select sid ,type,lmode,request from v$lock where sid in(148,159) order by sid;
SID TY LMODE REQUEST
---------- -- ---------- ----------
148 TX 6 0
148 TM 3 0
159 TX 6 0
159 TM 3 0
12. 这时在窗口一执行commit:
SQL> commit;
Commit complete.
13. 这时再用sys用户查看fortune 用户所占有的锁及类型:
SQL> select sid ,type,lmode,request from v$lock where sid in(148,159) order by sid;
SID TY LMODE REQUEST
---------- -- ---------- ----------
159 TX 6 0
159 TM 3 0
可以看到sid为148的锁已经释放了,只有sid 159所占有的锁了.
14. 这时在窗口二执行commit:
SQL> commit;
Commit complete.
15. 这时再用sys用户查看fortune 用户所占有的锁及类型:
SQL> select sid ,type,lmode,request from v$lock where sid in(148,159) order by sid;
no rows selected
SQL> select * from test1;
A1 A2
---------- ----------
1 1
2 100
3 500
4 867
5 888
5 988
发现没有锁了,记录已经添加成功了.
二. Update 时锁的占用情况:
1. 在窗口一执行一个update:(不要commit)
SQL> update test1 set a2='999' where a1=4;
1 row updated.
2. 同样在窗口二也执行一个update,更新同一行数据: (不要commit)
SQL> update test1 set a2='1000' where a1=4;
1 row updated.
这时可以看到这个窗口已经停止反应了.
3. 这时用sys用户查看fortune用户的锁情况,如下:
SQL> select sid ,type,lmode,request from v$lock where sid in(148,159) order by sid;
SID TY LMODE REQUEST
---------- -- ---------- ----------
148 TM 3 0
148 TX 6 0
159 TM 3 0
159 TX 0 6
发现159的TX类型的锁里,request 为6,是在等待另外一个锁
4. 这时用sys查看一下sid 159对应的系统事件:
SQL> select sid,event from v$session where sid='159';
SID EVENT
---------- ----------------------------------------------------------------
159 enq: TX - row lock contention
可以看到159在等一个row lock的结束.
5. 这时在窗口一执行commit:
SQL> commit;
Commit complete.
6. 这时在窗口二的update就有反应了.
7. 这时再用sys查看一下sid 159对应的系统事件:
SQL> select sid,event from v$session where sid='159';
SID EVENT
---------- ----------------------------------------------------------------
159 SQL*Net message from client
在这可以看到等待结束了.
SQL> select sid ,type,lmode,request from v$lock where sid in(148,159) order by sid;
SID TY LMODE REQUEST
---------- -- ---------- ----------
159 TX 6 0
159 TM 3 0
以上可以看到,sid 148占有的锁已经都释放了.
SQL> select * from test1;
A1 A2
---------- ----------
1 1
2 100
3 500
4 999
5 888
5 988
在这也可以看到a1=4这一行的A2值已经被更新为999了.
8. 这时再到窗口二执行commit.
SQL> commit;
Commit complete.
再看锁的情况,发现fortune用户的锁都已经释放了.
SQL> select sid ,type,lmode,request from v$lock where sid in(148,159) order by sid;
no rows selected
SQL> select * from test1;
A1 A2
---------- ----------
1 1
2 100
3 500
4 1000
5 888
5 988
在这也可以看到a1=4这一行的A2值已经被更新为1000了.
三. 锁的解除.
1. 在窗口一上执行以下更新:
SQL> update test1 set a2='1111' where a1=3;
1 row updated.
2. 在窗口二执行以下更新:
SQL> update test1 set a2='2222' where a1=3;
这时和上面一样,可以看到窗口二hang住了,没反应了. 我等了半小时还是一样
3. 这时用sys用户来查询一下fortune的锁情况:
SQL> select sid ,type,lmode,request from v$lock where sid in(148,159) order by sid;
SID TY LMODE REQUEST
---------- -- ---------- ----------
148 TM 3 0
148 TX 6 0
159 TM 3 0
159 TX 0 6
可以看到和前面的结果是一样的,sid 159在等148的一个锁释放掉.
4. 使用以下语句来查一下锁的情况:
SQL> select A.sid, b.serial#,
decode(A.type,
'MR', 'Media Recovery',
'RT','Redo Thread',
'UN','User 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 Invalida-tion',
'LS', 'Log Start or Switch',
'RW', 'Row Wait',
'SQ', 'Sequence Number',
'TE', 'Extend Table',
'TT', 'Temp Table',
'Unknown') LockType,
c.object_name,
---b.username,
---b.osuser,
decode(a.lmode, 0, 'None',
1, 'Null',
2, 'Row-S',
3, 'Row-X',
4, 'Share',
5, 'S/Row-X',
6, 'Exclusive', 'Unknown') LockMode,
B.MACHINE,D.SPID ,b.PROGRAM
from v$lock a,v$session b,all_objects c,V$PROCESS D
where a.sid=b.sid and a.type in ('TM','TX')
and c.object_id=a.id1
AND B.PADDR=D.ADDR
---order by username
;
SID SERIAL# LOCKTYPE OBJECT_NAME LOCKMODE MACHINE SPID PROGRAM
---------- ---------- --------- ------------------------------
148 18 DML TEST1 Row-X qatest006 11173 sqlplus@qatest006(TNS V1-V3)
159 176 DML TEST1 Row-X qatest006 11493 sqlplus@qatest006(TNS V1-V3)
或者用以下语句也可以:
SQL> select sid,serial# from v$session User_Info;
SID SERIAL#
---------- ----------
132 14
133 774
147 603
148 18
151 1
154 1
158 4582
159 176
160 1
161 1
162 1
SID SERIAL#
---------- ----------
163 1
164 1
165 1
166 1
167 1
168 1
169 1
170 1
5. 用以下语句来结束窗口一的锁session.
SQL> alter system kill session '148,18';
System altered.
这时到窗口二可以看到窗口有反应了.update成功了(但还没有commit.)
6. 这时如果在窗口一执行commit.可以看到以下报错.
SQL> commit;
commit
*
ERROR at line 1:
ORA-00028: your session has been killed
7. 这时到窗口二执行commit.
SQL> commit;
Commit complete.
SQL> select * from test1;
A1 A2
---------- ----------
1 1
2 100
3 2222
4 1000
5 888
5 988
可以看到更新已经完成.
阅读(1055) | 评论(0) | 转发(0) |