简单演示 FOR UPDATGE [NOWAIT] 阻塞

会话 session 1:

SQL> select distinct sid from v$mystat;
 
       SID
----------
       145
 
SQL> create table t as select rownum id from dba_users;
 
表已创建。

若修改 id>10 的记录:

SQL> select * from t where id>10 for update;
 
        ID
----------
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
 
        ID
----------
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
 
        ID
----------
        33
        34
        35
        36
        37
 
已选择27行。
 
SQL>

打开会话 session 2:

SQL> select distinct sid from v$mystat;
 
       SID
----------
       142
 
SQL> select * from t where id>10 for update;

这时,session 2 就会被阻塞,因为 session 2 需要等待 session 1 的操作结果。

SQL> select sid,type,id1,id2,lmode,request,block
  2  from v$lock where sid in (145,142)
  3  order by sid;
 
       SID TYPE         ID1        ID2      LMODE    REQUEST      BLOCK
---------- ----- ---------- ---------- ---------- ---------- ----------
       142 TX        327712      46191          0          6          0
       142 TM        129305          0          3          0          0
       142 AE            99          0          4          0          0
       145 TX        327712      46191          6          0          1
       145 TM        129305          0          3          0          0
       145 TO         62986          1          3          0          0
       145 AE            99          0          4          0          0
 
已选择7行。
 
SQL>

session 1 持有一个 lmode=6 的事务锁(TX),而 session 2 等待这个事务锁,block=1 表示当前会话阻塞了其他会话。

如果程序设置成这样,通常会保护 session 1 用户的数据,但是对于 session 2 用户来说,如果 session 1 迟迟不提交,将会一直等下去,对于用户来说,它很可能不知道发生了什么情况,也不知道要等待多长时间。

如果 session 2 不愿意等待,可以通过如下操作来获得一个错误通知而悟无需等待。

若会话 session 1:

SQL> select * from t where id>10 for update nowait;
 
        ID
----------
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
 
        ID
----------
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
 
        ID
----------
        33
        34
        35
        36
        37
 
已选择27行。
 
SQL>

在会话 session 2:

SQL> select * from t where id>10 for update nowait;
select * from t where id>10 for update nowait
*
第 1 行出现错误:
ORA-00054: 资源正忙, 但指定以 NOWAIT 方式获取资源, 或者超时失效
 
 
SQL>

通过使用 nowait 选项,可以让后续操作的用户不必等待而直接收到一个错误信息。在有人为干预的情况下,这种错误提示无疑会有助于故障的判断。

但对于一个自动运行的系统来说,等待,似乎更合理写,尽管要等待,但它能够保证系统正常运行而不会中断。

posted @ 2013-03-25 21:30  船长&CAP  阅读(316)  评论(0编辑  收藏  举报
免费流量统计软件