Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

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

like image 346
user1 Avatar asked Nov 06 '12 09:11

user1


People also ask

What is for update clause in cursors?

The FOR UPDATE clause is an optional part of a SELECT statement. Cursors are read-only by default. The FOR UPDATE clause specifies that the cursor should be updatable, and enforces a check during compilation that the SELECT statement meets the requirements for an updatable cursor.

What does Nowait and wait mean in the context of updating with cursors?

The FOR UPDATE NOWAIT simply means that you do not want to wait to lock a row, when that row is already locked for change by someone else. So should an already locked row be encountered, Oracle will return an exception telling you that. (

When should we use cursor in Oracle?

Cursors are used when the user needs to update records in a singleton fashion or in a row by row manner, in a database table. The Data that is stored in the Cursor is called the Active Data Set. Oracle DBMS has another predefined area in the main memory Set, within which the cursors are opened.

What is the use of where current of in cursors?

The WHERE CURRENT OF clause is a clause in some UPDATE and DELETE statements. It allows you to perform positioned updates and deletes on updatable cursors.


1 Answers

Using for update nowait will 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 expired instead of waiting the lock to release.

Session1:

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:

Session2:

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.

EDIT Suppose there are 10 rows in temp and I execute the following script in my session 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

select * from temp;

10 rows found 

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

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.

like image 54
Gaurav Soni Avatar answered Sep 28 '22 03:09

Gaurav Soni