ITPub博客

首页 > Linux操作系统 > Linux操作系统 > oracle select for update

oracle select for update

原创 Linux操作系统 作者:OraFige 时间:2011-12-20 14:25:44 0 删除 编辑
Normal 0 false false false EN-US ZH-CN X-NONE1.创建实验表table_sfu,并初始化三条数据
sec@ora10g> create table table_sfu (a number);

Table created.

sec@ora10g> insert into table_sfu values (1);

1 row created.

sec@ora10g> insert into table_sfu values (2);

1 row created.

sec@ora10g> insert into table_sfu values (3);

1 row created.

sec@ora10g> commit;

Commit complete.

sec@ora10g> select * from table_sfu;

         A
----------
         1
         2
         3

2.使用Select For Update语句得到第一条数据
sec@ora10g> select * from table_sfu where a = 1 for update;

         A
----------
         1

3.查看一下现在系统中的锁定情 况,152会话(即上面语句所在的会话)获得了一个TX锁和一个TM锁了,锁定的表就是TABLE_SFU
sec@ora10g> @lock

lock        lock
holder    holder         lock             lock request       blocked
username  sessid SERIAL# type    id1  id2 mode    mode BLOCK  sessid
-------- ------- ------- ---- ------ ---- ---- ------- ----- -------
SEC          152   14985 TM    15396    0    3       0     0
SEC          152   14985 TX   327722 1790    6       0     0
             164       1 TS        3    1    3       0     0
             165       1 CF        0    0    2       0     0
             165       1 RS       25    1    2       0     0
             165       1 XR        4    0    1       0     0
             166       1 RT        1    0    6       0     0

7 rows selected.

sec@ora10g> col OWNER for a6
sec@ora10g> col OBJECT_NAME for a10
sec@ora10g> select OWNER,OBJECT_NAME,OBJECT_ID,OBJECT_TYPE from dba_objects where object_id = '15396';

OWNER  OBJECT_NAM  OBJECT_ID OBJECT_TYPE
------ ---------- ---------- -------------------
SEC    TABLE_SFU       15396 TABLE

4.另外新打开一个session,执行以下修改任务
sec@ora10g> update table_sfu set a = 100 where a = 1;
OK,效果出现了,这里出现了锁等待现象,原因就是因为在第一个session中使用 Select For Update语句锁定了第一行数据,不允许其他的session对它修改。

5.这时系统中锁定情况如下,可 以看到第一个sessionsession id152)会话锁定了第二个sessionsession id145)会话的事务
sec@ora10g> @lock

lock        lock
holder    holder         lock             lock request       blocked
username  sessid SERIAL# type    id1  id2 mode    mode BLOCK  sessid
-------- ------- ------- ---- ------ ---- ---- ------- ----- -------
SEC          145   11388 TM    15396    0    3       0     0
SEC          152   14985 TM    15396    0    3       0     0
SEC          152   14985 TX   327722 1790    6       0     1     145
             164       1 TS        3    1    3       0     0
             165       1 CF        0    0    2       0     0
             165       1 RS       25    1    2       0     0
             165       1 XR        4    0    1       0     0
             166       1 RT        1    0    6       0     0

8 rows selected.

6.因为仅仅是锁定了第一条数 据,所以其他记录可以顺利的进行修改,如下
sec@ora10g> update table_sfu set a = 200 where a = 2;

1 row updated.

sec@ora10g> commit;

Commit complete.

7.解锁方式:commit rollback后即完成锁定的接触

8. 反过来思考一下,如果Select For Update与要锁定的行已经在其他session中完成了修改,再执行回出现什么效果呢?这个很显然,同样的会出现锁等待的现象,不过我想强调的 是,这里可以使用nowaitwait选项来进行探测待锁定行是否可被锁定
实验效果如下:
第一个session
sec@ora10g> update table_sfu set a = 100 where a = 1;

1 row updated.

第二个session
sec@ora10g> select * from table_sfu where a = 1 for update;
此处是锁等待效果

sec@ora10g> select * from table_sfu where a = 1 for update nowait;
select * from table_sfu where a = 1 for update nowait
              *
ERROR at line 1:
ORA-00054: resource busy and acquire with NOWAIT specified
这里提示了错误,原因就是已经探测到该行已经被别的事务锁定,这里无法对其进行锁定操作。

sec@ora10g> select * from table_sfu where a = 1 for update wait 3;
select * from table_sfu where a = 1 for update wait 3
              *
ERROR at line 1:
ORA-30006: resource busy; acquire with WAIT timeout expired
这里提示的错误内容与上面的一 样,不过这里wait 3表示,我等你三秒的时间,如果三秒过后还无法锁定资源,就报错。

9.更进一步,请参考Oracle官方文档中相关的描述
for_update_clause ::=
http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/statements_10002.htm#i2126016
语法格式:
FOR UPDATE
[ OF [ [ schema. ]
       { table | view } . ]column
       [, [ [ schema. ]
            { table | view } . ]column
       ]...
]
[ NOWAIT | WAIT integer ]

同上述连接,搜索关键字 “for_update_clause”可以得到每个选项的解释信息

Using the FOR UPDATE Clause: Examples
http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/statements_10002.htm#i2130052

10.小结
上面的小实验展示了一下 Select For Update行级锁定的效果,Oracle的锁定机制还是非常的灵活的,基于这个锁定可以实现悲观锁定

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/26464953/viewspace-713614/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2011-11-21

  • 博文量
    28
  • 访问量
    61344