Help, question about "select ... for update nowait"
There is a proc code. In the beginning of the code, I used a SQL "select ... for update nowait" in order to prevent from another proc executing at the same time. When the case happens, "-54, ORA-00054: resource busy and acquire with NOWAIT specified" will be printed in the screen.
But there is a question: I need to print sth to indicate "another proc is running". I used "if (sqlca.sqlcode == -54)" as precondition, such as:
if (sqlca.sqlcode == -54) {
printf("There is another proc running.\n");
However, this line will not be printed. I doubt that the code quits directly when using "select ... for update nowait" so as not to set value (-54) to sqlca.sqlcode.
So, could you suggest whether there is another way that I can use to print "There is another proc running" when another proc is running?
Thx a lot for your kindly reply.
Yes, that link. Scroll down a bit and you will see:
The calling application gets a PL/SQL exception, which it can process using the error-reporting functions SQLCODE and SQLERRM in an OTHERS handler. Also, it can use the pragma EXCEPTION_INIT to map specific error numbers returned by raise_application_error to exceptions of its own, as the following Pro*C example shows:
EXEC SQL EXECUTE
/* Execute embedded PL/SQL block using host
variables v_emp_id and v_amount, which were
assigned values in the host environment. */
DECLARE
null_salary EXCEPTION;
/* Map error number returned by raise_application_error
to user-defined exception. */
PRAGMA EXCEPTION_INIT(null_salary, -20101);
BEGIN
raise_salary(:v_emp_id, :v_amount);
EXCEPTION
WHEN null_salary THEN
INSERT INTO emp_audit VALUES (:v_emp_id, ...);
END;
END-EXEC;
This technique allows the calling application to handle error conditions in specific exception handlers.
Similar Messages
-
Should i use SELECT for update NOWAIT ?
Hi:
Do I need to use, in my pl/sql triggers and procedures, the SELECT FOR UPDATE NOWAIT sentence, to avoid locks before using update table sentences ? Is it common to use it on stored procedures and triggers?
Thanks
Joao OliveiraFirst, what, exactly do you mean by "avoid locks"? I was interpreting that to mean "I want to avoid creating locks in my session that might block someone else", not "I want to avoid having my SELECT wait for locks to be released-- I want it to fail immediately". If you meant the latter, then SELECT ... FOR UPDATE NOWAIT would be what you want. If you meant the former, then pessimistic locking is not what you want.
Second, what sort of Oracle Forms architecture do you have? Are you still using old-school client-server applications? Or are you using a three-tiered approach? As Tom discusses in that thread, pessimistic locking is only an option when your client application is able to maintain database state across calls (i.e. client/server systems) not when you have stateless connections (which is the norm in the three-tier model). The old client-server versions of Forms would automatically and transparently do pessimistic locking. Since you didn't mention anything about your architecture, most of us probably assumed the more common stateless client architecture (note how Tom's answers progress over the 5 years in that thread as client/server architecture became less and less common).
Third, while your question is appropriate for either the Database - General forum or the SQL and PL/SQL forum, that generally means that you are free to post it either forum, not that it should be posted in both. The vast majority of the folks that hang out in one forum hang out in the other. It's also rather frustrating to answer a post in one forum only to discover that there is another post in a different forum where someone else had already covered the same points half an hour earlier or to discover that there was additional information in another thread that might have changed your answer.
Fourth, if you are going to do pessimistic locking, that requires that you are able to maintain state across various database calls, that you are locking on the lowest possible level of granularity, and that you are able to time out sessions relatively aggressively to ensure that someone doesn't open a record, thereby locking it, go to lunch (or have their system die) and then block everyone else from working. Assuming that is the case, and that you have some reasonable way to handle the error that gets generated other than simply retrying the operation, adding NOWAIT is certainly an option. Most applications, particularly those getting written today, cannot guarantee all these things, so pessimistic locking is generally not appropriate there.
Looking at your other thread (where there is new information that would be useful in this discussion, one of the reasons that multiple threads are generally a bad idea), it seems that you have an ERP application and you are concerned about the performance of entering orders. Obviously, there shouldn't be any locking issues on the ORDER or ORDER_DETAILS tables, assuming that multiple users aren't going to be inserting the same order at the same time. The contention would almost certainly come when multiple orders are trying to update the STOCK and INVENTORY tables, since multiple orders presumably rely on the same rows in those tables. In that case, I'm not sure what adding a NOWAIT would buy you-- unless you were going to roll back the entire order because someone is updating the STOCK row for #2 pencils and your order has an item of #2 pencils, you'd have to keep retrying the operation until you were able to modify the STOCK row, which would be less efficient than just letting that update block until the row was free.
Now, you could certainly redesign the application to minimize that contention by not trying to update what I assume are aggregate tables like STOCK and INVENTORY directly as part of your OLTP processing or, at least, by minimizing the time that you're locking a row. You could, for example, make STOCK and INVENTORY materialized views rather than tables that refresh ON COMMIT, which should decrease the time that your locks are held. You could also have those tables refreshed asynchronously, which would be even more efficient but may require that you reasses your holdback requirements.
Justin -
Hi everyone!
I have procedure that looks like this:
procedure set_expired_users(
p_QID integer,
p_Value integer default 1)
is
l_mdate timestamp(3) := null;
begin
l_mdate := get_mdate(p_Value);
MERGE INTO cached_lists cl
USING (SELECT distinct s.rootof as list_id, p_Value as is_expired, l_mdate as mdate
FROM zzz_userrelflat f, zzz_users u, zzz_temp_nn z, speclists s, lists_table lt
WHERE u.grp <> 1
AND f.userm = u.id
AND lt.id = z.id
AND f.userg = lt.ra
AND z.qid = p_QID
AND userm <> -2
AND s.ruser = userm) t
ON (cl.list_id = t.list_id)
when matched then
UPDATE SET cl.is_expired = t.is_expired, cl.mdate = decode(t.mdate, null, cl.mdate, t.mdate)
when not matched then
INSERT VALUES (t.list_id, t.is_expired, l_mdate);
end set_expired_users;As you can see there is no commit, commit executes in other stored procedures after that. in some cases I have bottleneck(enq TX), I rewrote procedure:
procedure set_expired_users(
p_QID integer,
p_Value integer default 1)
is
l_mdate timestamp(3) := null;
busy_lock exception;
PRAGMA exception_init(busy_lock,-54);
cursor cur_upd is
SELECT 1 from cached_lists cl where cl.list_id in (SELECT distinct s.rootof as list_id
FROM zzz_userrelflat f, zzz_users u, zzz_temp_nn z, speclists s, lists_table lt
WHERE u.grp <> 1
AND f.userm = u.id
AND lt.id = z.id
AND f.userg = lt.ra
AND z.qid = p_QID
AND userm <> -2
AND s.ruser = userm) FOR UPDATE NOWAIT;
begin
open cur_upd;
l_mdate := get_mdate(p_Value);
MERGE INTO cached_lists cl
USING (SELECT distinct s.rootof as list_id, p_Value as is_expired, l_mdate as mdate
FROM zzz_userrelflat f, zzz_users u, zzz_temp_nn z, speclists s, lists_table lt
WHERE u.grp <> 1
AND f.userm = u.id
AND lt.id = z.id
AND f.userg = lt.ra
AND z.qid = p_QID
AND userm <> -2
AND s.ruser = userm) t
ON (cl.list_id = t.list_id)
when matched then
UPDATE SET cl.is_expired = t.is_expired, cl.mdate = decode(t.mdate, null, cl.mdate, t.mdate)
when not matched then
INSERT VALUES (t.list_id, t.is_expired, l_mdate);
close cur_upd;
exception
when busy_lock then
null;
end set_expired_users;Is this a good method to exclude enq TX?
Sincerely,
Pavel.In my opinion, you shouldn't rewrite that procedure, but you should rethink (ie. streamline) the overall transaction and try to reduce the wait times between the procedure call and the commit/rollback.
-
[ORACLE 9] Select For Update Nowait - Managing the Nowait
Hi,
Our application ( Oracle E Business R11) has a Form that allows Updates.
The problem is, when a user updates a record in the form, we want to prevent another user to open the same form, to avoid locks.
So I thought that I could
a) issue a 'select ...for update nowait',
b) get a code from Oracle
c )and use this code to prevent the form to be reopened.
I tried catching the Nowait in the exception section but I cannot get it to work.
Here is my code:
declare
v_var varchar2(40) := '---';
lv_nom tmp_delegue_jbm.del_nom%type;
begin
v_var := 'Phase 1';
select del_nom
into lv_nom
from tmp_delegue_jbm
where del_id = 3
for update of del_nom nowait;
dbms_output.put_line( 'Phase: ' || v_var );
v_var := 'Phase 2';
update tmp_delegue_jbm
set del_nom = del_nom || ' in'
where del_id = 3;
dbms_output.put_line( 'Phase: ' || v_var );
exception
when others then -- Should deal with the nowait situation
dbms_output.put_line( 'Error: ' || v_var || ' - ' || sqlerrm );
end;
[End Code]
Many thanksFar easier to poke a value into memory using DBMS_APPLICATION_INFO.SET_ACTION or SET_MODULE and have any session calling the form check first to see of another session has it already opened. Just make sure your exception handlers clear the lock.
http://www.morganslibrary.org/reference/dbms_applic_info.html -
JDBC-thin on Solaris 2.7, 1002 on "FOR UPDATE NOWAIT"
Has there been a patch to allow SELECT... FOR UPDATE NOWAIT
in the jdbc thin connection layer?
I have a program which runs transactions against Oracle 7.3 or
8.05, and I'm finding that it works fine on my NT workstation
against, 7.3.4....
But when I run it against oracle 8.0.5 from a Solaris 2.7 system,
I'm getting ORA-1002 errors whenever I select for update nowait.
I'm oracle has a fix for this, but I haven't seen it yet.
I did see a message about BUG 597589 posted on 02-Sep-1998.
Was this ever fixed? The BUG database makes no mention of it.
The only work-around seems to be to set autocommit, but I suspect
that will lead to deadlocks in my application, if it even works!
Has anyone else dealt with this problem?
Thanks in advance,
Kevin Fries
nullHas there been a patch to allow SELECT... FOR UPDATE NOWAIT
in the jdbc thin connection layer?
I have a program which runs transactions against Oracle 7.3 or
8.05, and I'm finding that it works fine on my NT workstation
against, 7.3.4....
But when I run it against oracle 8.0.5 from a Solaris 2.7 system,
I'm getting ORA-1002 errors whenever I select for update nowait.
I'm oracle has a fix for this, but I haven't seen it yet.
I did see a message about BUG 597589 posted on 02-Sep-1998.
Was this ever fixed? The BUG database makes no mention of it.
The only work-around seems to be to set autocommit, but I suspect
that will lead to deadlocks in my application, if it even works!
Has anyone else dealt with this problem?
Thanks in advance,
Kevin Fries
null -
FOR UPDATE NOWAIT Fails to Detect Lock
Locking a bitmap indexed row would cause other rows locked. I heard that, if FOR UPDATE NOWAIT is used on these accidentally locked rows (Oracle SQL High Performance Turning by Prentice hall), it may not be able to detect the lock. Is it true? I cannot find related documenation from Oracle's manual. And, what should we do to prevent an incorrect lock status returned by FOR UPDATE NOWAIT?
SELECT FOR UPDATE NOWAIT detects locks affected DATA blocks.
Look the example below:
SQL> create table t1 (id number, bit_col number);
Table created.
SQL> begin
2 insert into t1 values(0,1);
3 insert into t1 values(1,1);
4 insert into t1 values(2,2);
5 insert into t1 values(3,3);
6 insert into t1 values(4,4);
7 end;
8 /
PL/SQL procedure successfully completed.
SQL> commit;
Commit complete.
SQL> create bitmap index t1_bit on t1(bit_col);
Index created.Now in session 1 we change the bitmap-indexed column and it affects
index node:
SQL> update t1
2 set bit_col = 4
3 where id = 2;
1 row updated.In accordance to bitmap index structure this operator locks the index section
the locked row pertains to:
2th session waits for the lock release even when it tries to lock another row -
two rows pertain to the same index section which is locked by the first session:
SQL> update t1
2 set bit_col = 2
3 where id = 3;After rollback in the first session the second one gets the resource:
SQL> update t1
2 set bit_col = 2
3 where id = 3;
1 row updated.Now lets do rollback in both and repeate the first UPDATE in the first session:
SQL> update t1
2 set bit_col = 4
3 where id = 2;
1 row updated.In the second session we can lock the row (not index section) using
SELECT FOR UPDATE:(in contrast with UPDATE statement which changes
indexed column):
SQL> select * from t1 where id=3 for update nowait;
ID BIT_COL
3 3But certainly we detect row-level lock in the data block for ID = 2:
SQL> select * from t1 where id=2 for update nowait;
select * from t1 where id=2 for update nowait
ERROR at line 1:
ORA-00054: resource busy and acquire with NOWAIT specifiedRgds. -
Hello everyone,
I am working on a jsp/servlet project now, and got questions about which is the better way to deal with concurrent writing issues.
The whole senario is described as following:
First each user is viewing his own list of several records, and each record has a hyperlink through which user can modify it. After user clicks that link, there will be a popup window pre-populated with the values of that record, then user can do the modifications. After he is done, he can either click "Save " to save the change or "Cancel" to cancel it.
Method1---This is the method I am using right now.
I did not do any special synchronization measures, so if user 1 and user2 click the link of same record, they will modify the record
at the same time, then whose updates will take effect depends on who submits the request later. If user1 submitted first, then user 2, user1
will not see his updates. I know with this method, we will have the problem of "Lost Updates", but this is the simplest and efficient way to handle this issue.
Method2--This is the method I am hesitating.
I am considering to use "Select....for update nowait " to lock a record when user1 has selected one record and intended to modify it. If user2 wanted to modify the same record, he is not allowed. ( by catching the sql exception.)But the issue I am concerned about is because the "select .. For update" action and "Update action" are not so consecutive as many transaction examples described. There could be a
big interval between " select " and "update" actions. You could not predict user's behavior, maybe after he open the popup window, it took him a while to make up his decision, or even worse, he was interrupted by other things and went away for the whole morning?.Then the lock is just held until he releases it.
And another issue is if he clicks "cancel" to cancel his work, if I use method1, I don't need to interact with server-side at all, but if user method2, I still need to interact with the server to release the lock.
Can someone give me some advice ? What do you do to deal with similar situation? If I did not make clear of the question, please let me know.
Thanks in advance !
RachelHi Rachel,
Congratulation, you have found a way to overcome your programming business logic.
Have you ever consider that the solution of using CachedRowset concept yet to be included in j2se 1.5 tiger next year too prove workable under the scenario , whereby you can disconnect from the database after you have execute your query and reconnect again if you have to do transactional activity later, so that the loading overhead as well as the data pooling activity could be well balanced off.
Although rowset is still not an official API now, but its potential to me is worth consideration.
I have written a simple but crude cut JSP programme posted on this forum under the heading "Interesting CachedRowset JSP code to share " to demonstrate the concept of CachedRowset and hoping that the Java guru or the developer could provide feedback on how to imporve on the programming logic or methodology.
Thanks!! -
Ansi SQL for "select ... for update nowait"
Hi, All,
I have a sql
select ... for update nowait
My boss wants it to be ANSI compliant.
I am not familiar with ANSI SQL.
What should be the syntax in Ansi?
Thanks a lot!I resent having the lowest salary :-)Sorry John, it's probably due to the exchange rate of sterling against the canuck dollar right now.
SQL> select empno, ename, sal, job, mgr from emp;
EMPNO ENAME SAL JOB MGR
7369 SPENCER 800 CLERK 7902
7499 VERREYNNE 1600 SALESMAN 7698
7521 VAN WIJK 1250 SALESMAN 7698
7566 MAINGUY 2975 MANAGER 7839
7654 KISHORE 1250 SALESMAN 7698
7698 BARRY 2850 MANAGER 7839
7782 BOEHMER 2695 MANAGER 7839
7788 PADFIELD 3000 ANALYST 7566
7839 SCHNEIDER 5500 PRESIDENT
7844 GASPAROTTO 1500 SALESMAN 7698
7876 CAVE 1100 CLERK 7788
7900 CLARKE 950 CLERK 7698
7902 JAFFAR 3000 ANALYST 7566
7934 ROBERTSON 1430 CLERK 7782
14 rows selected.
SQL> Cheers, APC -
How to remove Help - About - "Check for updates"
I need to disable completelly all update possibilities from Firefox 4 installation and this is still something that I have not been able to remove.
inside omni.jar I have found similar configuration files that have been working also in prevoius FF versions and have been able to remove update tab completelly from Tools - Options -> Advanced but I have not been able to remove this update button from FF.
I thought that I found correct file to change:
"omni.jar\chrome\browser\content\browser -> aboutdialog.xul" but modifying that does not affect at all to this About - check for updates button.
Any ideas? I have tried to check other files also for this, but have not yet found anything, unfortunately...A possibility is to use CSS code in userChrome.css or create an extension that adds this code.
<pre><nowiki>@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"); /* only needed once */
#updateBox { display:none !important; }</nowiki></pre>
* http://kb.mozillazine.org/Editing_configuration -
Lock Cascade With Select for UPDATE
If I had a employee table and a phone table with a parent/child relationship and a primary key constraint on the employee table-will issuing a select for update on the employee also lock the corresponding child rows on the phone table ?
If not how can I bring this about ?You only need two sessions:
First session: Issue the 'select for update'
statements for the row(s) in both tables, don't
rollback or commit
Second session: try to update a row that you tried to
lock in the first session (with NOWAIT).
Thanks. I can try this definitely. A basic question.
You are asking me to do a join on both the tables right ?
Not two individual SQL statements ?
Updating the primary key is known as a Bad Idea (tm).
The key should never be touched because it should be
meaningless. When you have a column that holds 'real'
information it is no candidate for a primary key.
Rgds,
GuidoYes I am aware of that. I was just wondering what is the meaning behind this statement from this link ?
http://www.akadia.com/services/ora_locks_survival_guide.html
And the exact phrase from that link under the section Referential Integrity Locks (RI Locks)
"RI constraints are validated by the database via a simple SELECT from the dependent (parent) table in question-very simple, very straightforward. If a row is deleted or a primary key is modified within the parent table, all associated child tables need to be scanned to make sure no orphaned records will result. "
Thanks again. -
Clarification on SELECT for UPDATE
HI All,
I am doing a SELECT FOR UPDATE using NOWAIT as well as SKIPLOCKED option. I have question regarding the general behavior.
Suppose let say , I have two tables (table1 and table 2 ).
TABLE 1
header_id NUMBER,
service_id NUMBER
TABLE 2
header_id NUMBER,
line_id NUMBER,
status VARCHAR2
And I run the following query
SELECT t2.header_id, t2.line_id
FROM table1 t1, table2 t2
WHERE t1.header_id = t2.header_id
AND t1.service_id = 1
AND t2.status = 'SUCCESS'
FOR UPDATE OF t2.status NOWAIT SKIP LOCKED;
Questions
1) Does adding both the NOWAIT and SKIP LOCKED in the sql help or just SKIP LOCKED would do fine.
2) Lets say this SQL is executed when there are no rows with status as 'SUCCESS' in table2. Would this cause any performance impact. Like for example since its joining with table1 with table 2 based on the header id .Would it lock any rows on table1?
( My understanding was that it would not lock any row until it finds out any row with status as 'SUCCESS' but getting some conflicting answers)
Thanks,
VjAKVK wrote:
( My understanding was that it would not lock any row until it finds out any row with status as 'SUCCESS' but getting some conflicting answers)THis would be my understanding too.
To be sure make a test.
Do the select for update so that it does not lock any rows.
Then check the data dictionary select * from v$lock; to see for your session if there are any locks. -
How do I view data being locked by select for update
We've implemented a test appointment booking system. The application does explicit row locking (e.g. select * from calendar where ..... for update nowait;)
I need to view which database SID and USER has which records locked.
I cannot find such SQL on google or AskTom.
Currently, I can figureout which records are locked with the following PL/SQL.
set serveroutput on
declare id varchar2(20);
begin
for r in (select rowid,a.* from CALENDAR a) loop
begin
select rowid into id from CALENDAR where rowid=r.rowid for update nowait;
exception
when others then
dbms_output.put_line(r.rowid);
end;
rollback;
end loop;
rollback;
end;
Two questons:
1. How do I find out which database user and SID is locking each record.
2. Is there a more elegant way of instead of boing the above PL/SQL.
Please help?Oracle is not maintaining a list of all row locks. I've been told that other RDBMS's do have such a lock manager. Oracle doesn't because it hinders scalability. The fact that a row is locked is written in the block header itself. And you can only see that a row is locked by trying to lock it yourself. If it gives an ORA-00054, the row is locked.
However, I've seldom come across a situation where I need to know which rows are locked. So what's the real reason behind your requirement "I need to view which database SID and USER has which records locked.". Why is this information important to you?
Regards,
Rob.
PS: About your code: you don't want to catch the OTHERS exception, just the ORA-00054. -
Error message: "playlists selected for updating no longer exist"
I tried to update my ipod nano and I guess I had deleted a playlist, but since then, I have not been able to update. Every time I try, I get the following message:
"Cannot be updated because all of the playlists selected for updating no longer exist."
I haven't been able to highlight which playlists are selected to begin with.
I read through the manual and thought that maybe rebooting the whole system might work. So I deleted Itunes from my computer and re-installed.
Then I tried re-setting my ipod. So now I have nothing on my ipod.
I also deleted everything from my library, thinking it might help to start from scratch. Nothing has worked.
How do I "select" and "unselect" playlists so I can get up and running again?Here you go.
http://discussions.apple.com/thread.jspa?messageID=607312򔑐 -
Lost music on ipod because "playlists selected for updating no longer exist
Not sure what I've done. I recently downloaded newer version of itunes. Then when synching, I had too much music in my library for the ipod to handle so it told me about doing the smart playlist. I erased a couple of playlists on the itunes menu I no longer wanted and then when I went to synch, this error came up "songs on the ipod cannot be updated because all of the playlists selected for updating no longer exist."
Please help.....Check this out.
iPod cannot sync because one or more playlist.... -
"Playlists selected for updating no longer exist"?!
everytime i plug my ipod mini into the computer, a pop up appears saying that the playlists selected for updating no longer exist!!! it's done this before, so i completely restored the setting and made a whole new library. now it's doing it again. i have all the playlists and songs on my computer in a folder. all the songs that were on my ipod, got deleted when i plugged it into the computer. so my ipod is blank, but i have the songs in my library still. they just wont upload. any help would be greatly appreciated....
Check this out.
iPod cannot sync because one or more playlist....
Maybe you are looking for
-
hi All, I have one requirement.I wonder whether i can do it in a single SQL Statement or not. I have tab1 with columns c1,c2,c3,c4,....,Logon_time I have tab2 with columns C1,c2,c3,c4.....,Logoff_time All the columns are same for two tables except th
-
I have an iMac - 24 inch early 2009, What is the highest I could upgrade it to?
I have a 2.66 intel core 2 duo 4gb 1067 Mhz DDR3 Nvidia GeForce 9400 256mb I want it to be faster and handle video and imovie better. What upgrades are available and can I do it myself? Would I be better off buying a new mac?
-
Authentication in ADF App using BAM Data Control
Hi I' having problems with an ADF application using Oracle BAM Data Control. Whe I run the project I've the following error: According to Oracle Fusion Middleware Error Messages Reference seems to be an issues with the authentication against the JMS
-
Firefox browser does not recognize Java plugin in 64 bit Linux
I am running Firefox12 on RHEL5 with Java6u31 installed. Unfortunately firefox will not recognize the java plugin. I have tried linking it in the appropriate directory (https://support.mozilla.org/en-US/questions/760718?e=es&as=aaq) and I get nothing
-
When you report a problem on iTunes, how do they contact you with the resolution? is it by your E-Mail??