oracle for update nowait和for update区别
oracle for update nowait和for update区别
oracle for update nowait和for update区别Select...for update 语句是我们经常使用手工加锁语句。通常情况下,select语句是不会对数据加锁,妨碍影响其他的DML和DDL操作。借助for update子句,我们可以在应用程序的层面手工实现数据加锁保护操作。
一、加锁范围子句:
在select ....for update 之后,可以使用of子句选择对select的特定数据表进行加锁操作。默认情况下,不使用of子句表示在select所有的数据表中加锁。
二、使用for update的实例
1、select * from TTable1 for update --锁定表的所有行,只能读不能写
2、select * from TTable1 where pkid = 1 for update --只锁定pkid=1的行
3、select * from Table1 a join Table2 b on a.pkid=b.pkid for update --锁定两个表的所有记录
4、select * from Table1 a join Table2 b on a.pkid=b.pkid where a.pkid = 10 for update --锁定两个表的中满足条件的行
5、select * from Table1 a join Table2 b on a.pkid=b.pkid where a.pkid = 10 for update of a.pkid --只锁定Table1中满足条件的行
三、关于NOWAIT
当有LOCK冲突时会提示错误并结束STATEMENT而不是在那里等待(比如:要查的行已经被其它事务锁了,当前的锁事务与之冲突,加上nowait,当前的事务会结束会提示错误并立即结束 STATEMENT而不再等待).
如果加了for update后 该语句用来锁定特定的行(如果有where子句,就是满足where条件的那些行)。当这些行被锁定后,其他会话可以选择这些行,但不能更改或删除这些行,直到该语句的事务被commit语句或rollback语句结束为止。
因为FOR UPDATE子句获得了锁,所以COMMIT将释放这些锁。当锁释放了,该游标就无效了。
“使用FOR UPDATE WAIT”子句的优点如下:
1、防止无限期地等待被锁定的行;
2、允许应用程序中对锁的等待时间进行更多的控制。
3、对于交互式应用程序非常有用,因为这些用户不能等待不确定
4 、若使用了skip locked,则可以越过锁定的行,不会报告由wait n 引发的‘资源忙’异常报告
四、for update 和 for update nowait 的区别:
1、首先一点,如果只是select 的话,Oracle是不会加任何锁的,也就是Oracle对 select 读到的数据不会有任何限制,虽然这时候有可能另外一个进程正在修改表中的数据,并且修改的结果可能影响到你目前select语句的结果,但是因为没有锁,所以select结果为当前时刻表中记录的状态。
2、如果加入了for update, 则Oracle一旦发现(符合查询条件的)这批数据正在被修改,则不会发出该select语句查询,直到数据被修改结束(被commit),马上自动执行这个select语句。
3、同样,如果该查询语句发出后,有人需要修改这批数据(中的一条或几条),它也必须等到查询结束后(commit)后,才能修改。
4、for update nowait和 for update 都会对所查询到得结果集进行加锁,所不同的是,如果另外一个线程正在修改结果集中的数据,for update nowait 不会进行资源等待,只要发现结果集中有些数据被加锁,立刻返回 “ORA-00054错误,内容是资源正忙, 但指定以 NOWAIT 方式获取资源”。
5、for update 和 for update nowait 加上的是一个行级锁,也就是只有符合where条件的数据被加锁。如果仅仅用update语句来更改数据时,可能会因为加不上锁而没有响应地、莫名其妙地等待,但如果在此之前,for update NOWAIT语句将要更改的数据试探性地加锁,就可以通过立即返回的错误提示而明白其中的道理,或许这就是For Update和NOWAIT的意义之所在。
6、以for update 或 for update nowait方式进行查询加锁,在select的结果集中,只要有任何一个记录在加锁,则整个结果集都在等待系统资源(如果是nowait,则抛出相应的异常)
五、for update 和 for update nowait 的实例
1、数据
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');
SQL调用
--在plsql develope中打开两个sql窗口,
--在1窗口中运行sql
select * from t where a='1' for update;
--在2窗口中运行sql1
1. select * from t where a='1'; --这一点问题也没有,因为行级锁不会影响纯粹的select语句
--再运行sql2
2. select * from t where a='1' for update; --则这一句sql在执行时,永远处于等待状态,除非窗口1中sql被提交或回滚。
--如何才能让sql2不等待或等待指定的时间呢? 我们再运行sql3
3. select * from t where a='1' for update 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;
--在窗口2中执行:
select * from t where rownum<=6 nowait skip Locked;
select for update
备注:
select for update of,这个of子句在牵连到多个表时,具有较大作用,如不使用of指定锁定的表的列,则所有表的相关行均被锁定,若在of中指定了需修改的列,则只有与这些列相关的表的行才会被锁定。
热门推荐
- python四舍五入怎么用(python3 小数位的四舍五入用两种方法解决round 遇5不进)
- php服务号openid(php获取微信openid方法总结)
- sql查询过程解析(SQL 联合查询与XML解析实例详解)
- dedecms文章顺序(dedecms 分页标题提取方法)
- python如何判断是否为回文数(对python判断是否回文数的实例详解)
- python分析excel基础数据生成报表(Python实现定制自动化业务流量报表周报功能XlsxWriter模块)
- php数组取值方法(php给数组赋值的实例方法)
- php怎么引用文件(php引用和拷贝的区别知识点总结)
- docker pull 更新本地镜像(Docker 拉取镜像及标签操作 pull | tag)
- linux系统查看nginx系统版本(Linux中Nginx的防盗链和优化的实现代码)