SELECT...FOR UPDATE 语句  _MySQL, Oracle及数据库讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  MySQL, Oracle及数据库讨论区 »
总帖数
2
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 2547 | 回复: 1   主题: SELECT...FOR UPDATE 语句          下一篇 
flying
注册用户
等级:下士
经验:153
发帖:75
精华:0
注册:2011-8-25
状态:离线
发送短消息息给flying 加好友    发送短消息息给flying 发消息
发表于: IP:您无权察看 2015-7-24 14:18:04 | [全部帖] [楼主帖] 楼主

SELECT...FOR UPDATE 语句的语法如下: 

SELECT ... FOR UPDATE [OF column_list][WAIT n NOWAIT][SKIP LOCKED]; 

其中: 

  OF 子句用于指定即将更新的列,即锁定行上的特定列。 

  WAIT 子句指定等待其他用户释放锁的秒数,防止无限期的等待。 

  “使用FOR UPDATE WAIT”子句的优点如下:  

  1防止无限期地等待被锁定的行; 

  2允许应用程序中对锁的等待时间进行更多的控制。 

  3对于交互式应用程序非常有用,因为这些用户不能等待不确定 

  4 若使用了skip locked,则可以越过锁定的行,不会报告由wait n 引发的‘资源忙’异常报告



说明:

select * from t for update 会等待行锁释放之后,返回查询结果。

select * from t for update nowait 不等待行锁释放,提示锁冲突,不返回结果

select * from t for update wait 5   等待5秒,若行锁仍未释放,则提示锁冲突,不返回结果

select * from t for update skip locked 查询返回查询结果,但忽略有行锁的记录 



示例: 

create table t(a varchar2(20),b varchar2(20)); 

insert into t values('1','1'); 

insert into t values('2','2'); 

insert into t values('3','3'); 

insert into t values('4','4'); 

现在执行如下操作: 

在plsql develope中打开两个sql窗口, 

在1窗口中运行sql 

select * from t where a='1' for update;

结果:

A B

1       1

在2窗口中运行sql1 

1. select * from t where a='1';

结果:

A B

1       1

 这一点问题也没有,因为行级锁不会影响纯粹的select语句 

再运行sql2 

2. select * from t where a='1' for update; 

结果:

waiting.......



则这一句sql在执行时,永远处于等待状态,除非窗口1中sql被提交或回滚。

 

如何才能让sql2不等待或等待指定的时间呢? 我们再运行sql3 

3. 

select * from t where a='1' for update nowait;

结果:

ORA-00054: 资源正忙, 但指定以 NOWAIT 方式获取资源



则在执行此sql时,直接报资源忙的异常。 

若执行 

select * from t where a='1' for update wait 6; 

则在等待6秒后,报 资源忙的异常。 



如果我们执行sql4 

4. select * from t where a='1' for update nowait skip Locked; 

结果:

则执行sql时,即不等待,也不报资源忙异常。 



现在我们看看执行如下操作将会发生什么呢? 

在窗口1中执行: 


select * from t where rownum<=3 nowait skip Locked; (此处好像有错误,应该为: select * from t where rownum<=3 for update nowait skip Locked;  )
A B
2 2
3 3


在窗口2中执行: 

select * from t where rownum<=6 nowait skip Locked; 

( 此处好像有错误,应该为:select * from t where rownum<=6 for update  nowait skip Locked;可以跳过被窗口1中语句:select * from t where a='1' for update; 锁住的行)


A B
2 2
3 3
4 4


select for update 也就如此了吧,insert、update、delete操作默认加行级锁,其原理和操作与select for update并无两样。 

select for update of,这个of子句在牵连到多个表时,具有较大作用,如不使用of指定锁定的表的列,则所有表的相关行均被锁定,若在of中指定了需修改的列,则只有与这些列相关的表的行才会被锁定。



--转自 北京联动北方科技有限公司




赞(0)    操作        顶端 
联动大白
注册用户
等级:列兵
经验:91
发帖:0
精华:0
注册:2015-5-27
状态:离线
发送短消息息给联动大白 加好友    发送短消息息给联动大白 发消息
发表于: IP:您无权察看 2019-6-23 0:30:00 | [全部帖] [楼主帖] 2  楼

为了方便大家阅读,我对文章中错误号来解释一下吧!

Error Id: ORA-00054

Title: resource busy and acquire with NOWAIT specified

Description:

resource busy and acquire with NOWAIT specified

Action:

Retry if necessary.

Cause:

Resource interested is busy.


也许你已明白,但对一个人有用也是我存在的理由!^_^ By:持之以恒的大白

-- 来自: 北京联动北方科技有限公司



赞(0)    操作        顶端 
总帖数
2
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论