Chinaunix首页 | 论坛 | 博客
  • 博客访问: 302336
  • 博文数量: 94
  • 博客积分: 2220
  • 博客等级: 大尉
  • 技术积分: 975
  • 用 户 组: 普通用户
  • 注册时间: 2004-12-17 21:17
文章分类

全部博文(94)

文章存档

2011年(5)

2010年(11)

2009年(1)

2008年(2)

2006年(1)

2005年(65)

2004年(9)

我的朋友

分类: Oracle

2010-05-24 15:10:27


今天参考了一些文档,作了以下一点实验,记录了整个过程,留个记录吧。

一. 插入时锁的情况
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
可以看到更新已经完成.

阅读(1006) | 评论(0) | 转发(0) |
0

上一篇:陀螺

下一篇:阻止MSN传文件

给主人留下些什么吧!~~