oracle for update和for update of nowaitnowait的区别

oracle中UPDATE nowait 的使用方法介绍
字体:[ ] 类型:转载 时间:
UPDATE nowait 应用以下场景:查询某条数据,并对其开启数据库事务,感兴趣的朋友可以看看应用语句,希望可以帮助到你
1、UPDATE nowait 应用以下场景:查询某条数据,并对其开启数据库事务。如果查询的当前数据没有加锁,则正确返回结果,并对当前数据加锁,如果查询的当前数据已在事务中,已加锁。但返回异常信息:提示数据已加锁。SQL语句: Sql代码:
代码如下: SELECT * FROM hold_mc_site_product_pic pic WHERE pic.id = 730127 FOR UPDATE nowait
2、应用在多线程并发的情况下。先查询出要处理的数据,并加入数据库级的锁,处理完后,写入数据库。提交事务。可以有效控制并发情况下数据的一致性。
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具Oracle/PLSQL: SELECT FOR UPDATE Statement
Advertisement
Some functions
require javascript to be enabled to work. Please re-enable javascript in your browser settings.
Oracle/PLSQL: SELECT FOR UPDATE Statement
This Oracle tutorial explains how to use the Oracle/PLSQL SELECT FOR UPDATE statement with syntax and examples.
Description
The SELECT FOR UPDATE statement allows you to lock the records in the cursor result set. You are not required to make changes to the records in order to use this statement. The record locks are released when the next commit or rollback statement is issued.
The syntax for the SELECT FOR UPDATE statement in Oracle/PLSQL is:
CURSOR cursor_name
select_statement
FOR UPDATE [OF column_list] [NOWAIT];
Parameters or Arguments
cursor_name
The name of the cursor.
select_statement
A SELECT statement that will populate your cursor result set.
column_list
The columns in the cursor result set that you wish to update.
Optional. The cursor does not wait for resources.
For example, you could use the SELECT FOR UPDATE statement as follows:
SELECT course_number, instructor
FROM courses_tbl
FOR UPDATE OF
If you plan on updating or deleting records that have been referenced by a SELECT FOR UPDATE statement, you can use the
statement.
Share this page:
Advertisementselect...for update在mysql和oracle间锁行为的比较
select...for update在和oracle间锁行为的比较
mysql& show variables like '%storage_engine%'; &
+----------------+--------+ &
| Variable_name &| Value &| &
+----------------+--------+ &
| storage_engine | InnoDB | &
+----------------+--------+ &
1 row in set (0.00 sec) &
mysql& select version(); &
+-----------+ &
| version() | &
+-----------+ &
| 5.1.52 & &| &
+-----------+ &
1 row in set (0.06 sec) &
SQL& select * from v$version where rownum=1; &
---------------------------------------------------------------- &
Database 10g Enterprise Edition Release 10.2.0.1.0 - 64bi &
SQL& !uname -a &
Think 2.6.32-220.el6.x86_64 #1 SMP Wed Nov 9 08:03:13 EST
x86_64 x86_64 GNU/Linux &
& & 对mysql而言,select for update必须在一个事务中,当事务commit,锁也就释放了。因此,在实验时,务必加个begin、start transaction 或者 set autocommit=0。
& & mysql:
------------------sesson_A---------------: &
Query OK, 0 rows affected (0.00 sec) &
mysql& select * from t where i=2 &
+---+------+ &
| i | n & &| &
+---+------+ &
+---+------+ &
1 row in set (0.00 sec) &
------------------session_B---------------: &
mysql& select * &
+---+------+ &
| i | n & &| &
+---+------+ &
+---+------+ &
2 rows in set (0.00 sec) &
mysql& select * from t where i=2 &
被阻塞... &
mysql& update t set n='f' where i=2; &
被阻塞... &
mysql& alter table t drop index t_ &
被阻塞... &
mysql& delete from t where i=2; &
被阻塞... &
& & oracle:
-----------------------session_A--------------- &
SQL& select * from t where i=1 &
& & &I N &
---------- -------------------- &
& & &1 think big &
-----------------------session_B--------------- &
SQL& select * from t where i=1 &
被阻塞... &
SQL& update t set n='think open' where i=1; &
被阻塞... &
SQL& create index t_idx on t(i); &
create index t_idx on t(i) &
& & & & & & & & & & & * &
ERROR at line 1: &
ORA-00054: resource busy and acquire with NOWAIT specified &
SQL& delete from t where i=1; &
被阻塞... &
& & 于mysql,select ... for update 对行记录加个X锁。其他任何事务想在这些行上加任何锁都会被阻塞。这也符合InnoDB行级锁的概念。
& & 在oracle中,我们再做下一个测试:
-----------session_A------------- &
SQL& select * from t & &
&--------------session_B------------- &
SQL& select sid,type,lmode from v$lock where sid=159; &
& & & &SID TY & & &LMODE &
---------- -- ---------- &
& & & &159 TM & & & & &3 &
& & & &159 TX & & & & &6 &
& & 对oracle,当发出select ... for update的时候、得到的是RX锁(lmode=3),同时通过trc文件,我们还可以发现,Lck被置为1,也也就是同时被加上了行级锁。
& & trc部分摘录如下:
&Itl & & & & & Xid & & & & & & & & &Uba & & & & Flag &Lck & & & &Scn/Fsc &
0x01 & 0x000a.029.0000013b &0x008000dd.00c8.2b &C--- & &0 &scn 0xf4 &
0x02 & 0x0000a3.00c7.04 &--U- & &1 &fsc 0x9 &
tl: 5 fb: --H-FL-- lb: 0x2 &cc: 1 &
col &0: [ 1] &61&您的位置: >
oracle for update nowait和for update区别
学习标签:
本文导读:如果只是select 的话,Oracle是不会加任何锁的,如果加入了for update, 则Oracle一旦发现(符合查询条件的)这批数据正在被修改,则不会发出该select语句查询,直到数据被修改结束(被commit),马上自动执行这个select语句。nowait表示“不用等待,立即返回”,如果当前请求的资源被其他会话锁定时,会发生阻塞,nowait可以避免这一阻塞
Select...for update 语句是我们经常使用手工加锁语句。通常情况下,select语句是不会对数据加锁,妨碍影响其他的DML和DDL操作。借助for update子句,我们可以在应用程序的层面手工实现数据加锁保护操作。
一、加锁范围子句:
在select ....for update 之后,可以使用of子句选择对select的特定数据表进行加锁操作。默认情况下,不使用of子句表示在select所有的数据表中加锁。
SQL 代码 &&复制
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 的实例
SQL 代码 &&复制
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 --则在执行此sql时,直接报资源忙的异常。
select * from t where a='1' for update wait 6; 则在等待6秒后,报 资源忙的异常。
--如果我们执行sql4
4. select * from t where a='1' for update nowait skip L --则执行sql时,即不等待,也不报资源忙异常。
--在窗口1中执行:
select * from t where rownum&=3 nowait skip L
--在窗口2中执行:
select * from t where rownum&=6 nowait skip L
select for update
select for update of,这个of子句在牵连到多个表时,具有较大作用,如不使用of指定锁定的表的列,则所有表的相关行均被锁定,若在of中指定了需修改的列,则只有与这些列相关的表的行才会被锁定。
您可能感兴趣
一月好评排行榜

我要回帖

更多关于 mysql update nowait 的文章

 

随机推荐