In which case do we need to use for update nowait
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.
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. (
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With