oracle 什么时候应该在游标中使用“for update nowait”?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13248239/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 04:37:06  来源:igfitidea点击:

When should I use 'for update nowait' in cursors?

oraclestored-proceduresoracle11goracle10gcursor

提问by user1

In which case do we need to use for update nowaitin cursors.

在这种情况下,我们需要for update nowait在游标中使用。

回答by Gaurav Soni

Using for update nowaitwill cause the rows to be busy and acquires a lock until a commit or rollback is executed. Any other session that tries to acquire a lock will get an Oracle error message like ORA-00054: resource busy and acquire with NOWAIT specified or timeout expiredinstead of waiting the lock to release.

使用for update nowait将导致行忙并获取锁,直到执行提交或回滚。任何其他尝试获取锁的会话都将收到 Oracle 错误消息,ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired而不是等待锁释放。

Session1:

第 1 节:

CURSOR abc_cur 
IS 
select * from dept where deptno =10 for update nowait;

Here the rows are locked until the cursor is closed or a commit/rollback gets executed. If, meanwhile, another user from session 2 tries to access the same records then this will throw an error as shown below:

这里行被锁定,直到游标关闭或执行提交/回滚。同时,如果会话 2 中的另一个用户尝试访问相同的记录,则会引发如下所示的错误:

Session2:

会议2:

select * from dept where deptno =10 for update nowait;

This user cannot even update or delete the same records that have been locked by the first session.

此用户甚至无法更新或删除已被第一个会话锁定的相同记录。

ERROR at line 1:
`ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired`

Usage:Now if you want to do some manipulation on certain sets of records and you don't want another user from another session to override your data then you must first lock the records(using for update nowait) and then do your manipulation. After you're done with your manipulation, close the cursor and commit.

用法:现在,如果您想对某些记录集进行一些操作,并且不希望另一个会话中的其他用户覆盖您的数据,那么您必须首先锁定记录(使用for update nowait),然后进行操作。完成操作后,关闭游标并提交。

EDITSuppose there are 10 rows in temp and I execute the following script in my session 1 :

编辑假设 temp 中有 10 行,我在会话 1 中执行以下脚本:

declare
  cursor abc is select * from temp for update nowait;
  temp abc%rowtype;
begin
  open abc;
  -- do slow stuff here
  close abc;
  commit; 
end;

In session 2, I execute the following while the script in session 1 is still running

在会话 2 中,我在会话 1 中的脚本仍在运行时执行以下操作

select * from temp;

10 rows found 

If I execute the same script, in session 2, while the script in session 1 is still running

如果我在会话 2 中执行相同的脚本,而会话 1 中的脚本仍在运行

declare
  cursor abc is select * from temp for update nowait;
  temp abc%rowtype;
begin
  open abc;
  -- do slow stuff here
  close abc;
  commit; 
end;

Then I get ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired instead of waiting the lock to release.

然后我得到 ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired instead of waiting the lock to release.