Select for update query
with :
resultset = stmt.executeQuery("select nxtid from mytable .. for update");
I have the ora-1002 Erreur.
Could you help me.
null
<BLOCKQUOTE><font size="1" face="Verdana, Arial">quote:</font><HR>Originally posted by burgniar:
with :
resultset = stmt.executeQuery("select nxtid from mytable .. for update");
I have the ora-1002 Erreur.
Could you help me.<HR></BLOCKQUOTE>
Solution is :
conn.setAutoCommit(false);
null
Similar Messages
-
Select for update query not working..
hi i am tying to get this bit of ncode to work so i can then go to the next part of demonstrating a deadlock between two transactions. however i cannot go any further has my initial code does not work at all. here it goes
//////////User A////////////////////////////////
DECLARE
v_salary squad.salary%TYPE := 300;
v_pos squad.position%TYPE := 'Forward';
BEGIN
UPDATE squad
SET salary = salary + v_salary
WHERE sname = 'Henry';
FOR UPDATE;
UPDATE squad
SET position = v_pos
WHERE sname = 'Fabregas';
COMMIT;
END;
//////////////////////User B/////////////
DECLARE
v_salary squad.salary%TYPE := 200;
v_pos squad.position%TYPE := 'Forward';
BEGIN
UPDATE squad
SET position = v_pos
WHERE sname = 'Fabregas';
FOR UPDATE;
UPDATE squad
SET salary = salary + v_salary
WHERE sname = 'Henry';
FOR UPDATE;
COMMIT;
END;
Basicly user a creats a lock and so does user b, user b enquires a lock from user a and vice versa i.e. a deadlockHi
You get the following error:
ORA-06550: line 8, column 7:
PLS-00103: Encountered the symbol "UPDATE" when expecting one of the following:
because the FOR UPDATE; is invalid in your statement.
Try this:
//////////User A////////////////////////////////
DECLARE
v_salary squad.salary%TYPE := 300;
v_pos squad.position%TYPE := 'Forward';
v_n number;
BEGIN
UPDATE squad
SET salary = salary + v_salary
WHERE sname = 'Henry';
select 1 into v_n from squad
WHERE sname = 'Fabregas'
for update;
UPDATE squad
SET position = v_pos
WHERE sname = 'Fabregas';
COMMIT;
END;
//////////////////////User B/////////////
DECLARE
v_salary squad.salary%TYPE := 200;
v_pos squad.position%TYPE := 'Forward';
v_n number;
BEGIN
UPDATE squad
SET position = v_pos
WHERE sname = 'Fabregas';
select 1 into v_n from squad
WHERE sname = 'Henry'
for update;
UPDATE squad
SET salary = salary + v_salary
WHERE sname = 'Henry';
COMMIT;
END;
To syncronize the blocks first in a SQLPlus call these two statements:
select 1 from squad WHERE sname = 'Fabregas' for update;
select 1 from squad WHERE sname = 'Henry' for update;
After this start the user A code in another SQLPlus, and start the user B code. After this call rollback or commit in the first sqlplus.
Ott Karesz
http://www.trendo-kft.hu -
I have to do a "SELECT FOR UPDATE" query to modify a CLOB column.
The problem is that i want to release this lock BEFORE i commit or rollback de transaction.
How can i do it?
ThanksAlso, i want to release the lock to prevent a deadlock with another transaction, but without doing a commit, so i can rollback it if any error is produced after. You must remember that releasing the lock means that you are not interested in that part of the transaction (or the entire transaction). You cannot have the option of releasing the lock and preserving the transaction so as to allow others to do whatever with that data. This will violate transaction integrity.
Partial rollback seems to be what you need. If the driver is the problem, you could always package your logic into a procedure (prefarably in a package) and call that procedure from your driver (hoping the driver allows calling of stored procedures). -
Difference in select for update of - in Oracle Database 10g and 11g
Hi, I found out that Oracle Database 10g and 11g treat the following PL/SQL block differently (I am using scott schema for convenience):
DECLARE
v_ename bonus.ename%TYPE;
BEGIN
SELECT b.ename
INTO v_ename
FROM bonus b
JOIN emp e ON b.ename = e.ename
JOIN dept d ON d.deptno = e.deptno
WHERE b.ename = 'Scott'
FOR UPDATE OF b.ename;
END;
/While in 10g (10.2) this code ends successfully (well NO_DATA_FOUND exception is raised but that is expected), in 11g (11.2) it raises exception "column ambiguously defined". And that is definitely not expected. It seems like it does not take into account table alias because I found out that when I change the column in FOR UPDATE OF e.empno (also does not work) to e.mgr (which is unique) it starts working. So is this some error in 11g? Any thoughts?
Edited by: Libor Nenadál on 29.4.2010 21:46
It seems that my question was answered here - http://stackoverflow.com/questions/2736426/difference-in-select-for-update-of-in-oracle-database-10g-and-11gThe behaviour seems like it really is a bug and can be avoided using non-ANSI syntax. (It makes me wonder why Oracle maintains two query languages while dumb me thinks that this is just a preprocessor matter and query engine could be the same).
-
SELECT FOR UPDATE with the SKIP LOCK clause
Hi,
I have a query regarding the SELECT FOR UPDATE with the SKIP LOCK clause.
Whether this will be really good for parallel processing.
Also if we are selecting a set of records in a cursor whether the lock will be done at the records level once we fetch the records?
Also do we have any known issues with this one?
We are trying to figure out whether this will fit for business requirement, we are trying to do a implement a threading kind of thing for our stored procedure invocation in background using shell script.
Any suggestion or feedback on this will be helpful for us.
Thanks a lot for the support given....
Regards,
Basil Abraham.http://www.oracle.com/technology/oramag/oracle/08-mar/o28plsql.html
Please read the above thread for few information...Thanks! -
Deadlock detected during SELECT FOR UPDATE - an application error?
I have a general question about how Oracle prevents deadlocks from affecting
applications: do I need to build support into the application for handling
deadlocks when they occur in this particular scenario, or should Oracle handle
this for me? I'd like to know whether this is "normal" behavior for an Oracle
application, or if there is an underlying problem. Consider the following situation:
Two sessions issue individual SELECT FOR UPDATE queries. Each query locates
records in the table using a different index. These indexes point to rows in a
different order from each other, meaning that a deadlock will occur if the two
statement execute simultaneously.
For illustrative purposes, consider these rows in a hypothetical table.
ALPHABET
alpha
bravo
charlie
delta
echo
foxtrot
golf
hotel
Index A results in traversing the table in ascending alphabetical order; index
B, descending. If two SELECT FOR UPDATE statements concurrently execute on this
table--one with an ascending order execution path and one in descending order--
the two processes will deadlock at the point where they meet. If Session A
locks alpha, bravo, charlie, and delta, while Session B locks hotel, golf,
foxtrot, and echo, then neither process can proceed. A needs to lock echo, and
B needs to lock delta, but one cannot continue until the other releases its
locks.
This execution path can be encouraged using hints. Executing queries similar to these on larger tables will generate the "collision" as described above.
-- Session A
select /*+ index_asc (customer) */
from customer
where gender = 'M'
for update;
-- Session B
select /*+ index_desc (customer) */
from customer
where gender = 'M'
for update;
Oracle will recognize that both sessions are in a stand-off, and it will roll
back the work performed by one of the two sessions to break the deadlock.
My question pivots on whether or not, in this situation, the deadlock gets
reported back to the application executing the queries as an ORA-00060. If
these are the ONLY queries executed during these sessions, I would think that
Oracle would rollback the locking performed in one of the SELECT FOR UPDATE
statements. If I understand correctly,
(1) Oracle silently rolls back and replays work performed by UPDATE statements
when a deadlock situation occurs within the scope of the update statement,
and
(2) A SELECT FOR UPDATE statement causes Oracle, at the point in time the cursor
is opened, to lock all rows matching the WHERE clause.
If this is the case, then should I expect Oracle to produce an ORA-00060
deadlock detection error for two SELECT FOR UPDATE statements?
I would think that, for deadlock situations completely within Oracle's control,
this should be perceived to the application invoking the SELECT FOR UPDATE
statements as regular blocking. Since the query execution plans are the sole
reason for this deadlock situation, I think that Oracle would handle the
situation gracefully (like it does for UPDATE, as referenced in (1)).
Notice, from the trace file below, that the waits appear to be from row locking,
and not from an artificial deadlock (e.g. ITL contention).
Oracle8i Enterprise Edition Release 8.1.7.4.0 - 64bit Production
With the Partitioning option
DEADLOCK DETECTED
Current SQL statement for this session:
SELECT XXX FROM YYY WHERE ZZZ LIKE 'AAA%' FOR UPDATE
----- PL/SQL Call Stack -----
object line object
handle number name
58a1f8f18 4 anonymous block
58a1f8f18 11 anonymous block
The following deadlock is not an ORACLE error. It is a
deadlock due to user error in the design of an application
or from issuing incorrect ad-hoc SQL. The following
information may aid in determining the deadlock:
Deadlock graph:
---------Blocker(s)-------- ---------Waiter(s)---------
Resource Name process session holds waits process session holds waits
TX-002f004b-000412cf 37 26 X 26 44 X
TX-002e0044-000638b7 26 44 X 37 26 X
session 26: DID 0001-0025-00000002 session 44: DID 0001-001A-00000002
session 44: DID 0001-001A-00000002 session 26: DID 0001-0025-00000002
Rows waited on:
Session 44: obj - rowid = 0000CE31 - AAANCFAApAAAAGBAAX
Session 26: obj - rowid = 0000CE33 - AAANCHAArAAAAOmAAM
Thanks for your insight,
- Curtis
(1) "Oracle will silently roll back your update and restart it"
http://tkyte.blogspot.com/2005/08/something-different-part-i-of-iii.html
(2) "All rows are locked when you open the cursor, not as they are fetched."
http://download-east.oracle.com/docs/cd/A87860_01/doc/appdev.817/a77069/05_ora.htm#2170
Message was edited by:
Curtis LightThanks for your response. In my example, I used the indexes to force a pair of query execution plans to "collide" somewhere in the table in question by having one query traverse the table via index in an ascending order, and another in descending. This is an artificial scenario for reproducible illustrative purposes, but similar collisions could legitimately occur in real world scenarios (e.g. a full table scan and an index range scan with lookup by ROWID).
So, with that said, I think it would be unreasonable for Oracle to report the collision as a ORA-00060 every time it occurs because:
(1) The UPDATE statement handles this situation automatically, and
(2) An ORA-00060 results in a 100+KB trace file being written out, only rational for truly erroneous situations.
I agree that, when the application misbehaves and locks rows out of order in separate SQL statements, then Oracle should raise an ORA-00060, as the deadlock is outside of its control. But in this case, the problem occurs with just two individual SQL statements, each within its own transaction. -
Hi All,
I having block level 8000 records, I Scroll down from First record to last record it is takeing more time.
I Observed tkproof while scrolling two select statments are running..
1) pre-query block level
2) For update query
For update query -> How is is forming? Any Property or some else?
I am not able to find the second query..where it is forming..How to restrict the second query.
Query Array size - 10
Number of records buffered - 10
Number of records Displayed - 10
Query all records - No
Locking mode - Immediate
Key mode - Automatic
Version - Oracle 10g
Plz ........anyThe for update -query is generaetd by forms when its locking the record. If you didn't change anything in the record "by hand", check if there is some code in the POST-QUERY-trigger which forces the record to be locked. if its the POST-QUERY you can issue the following command to avoid the lock at the end of the POST-QUERY:
SET_RECORD_PROPERTY(:SYSTEM.TRIGGER_BLOCK, :SYSTEM.TRIGGER_RECORD, STATUS, QUERY_STATUS); -
Strange behavior of select for update
I observed a strange behavior of "select .. for update" statement in binary xml table. Here is the piece of code:
create table xmltab of XMLType XMLTYPE store as binary xml;
Table created.
insert into xmltab values('<x><y>y1</y><z>z1</z></x>');
1 row created.
select x.object_value
from xmltab x
where extractValue(x.object_value,'/x/y')='y1' and
extractValue(x.object_value,'/x/z')='z1' ;
OBJECT_VALUE
<x>
<y>y1</y>
<z>z1</z>
</x>
The following query doesn't return any row!!
select x.object_value
from xmltab x
where extractValue(x.object_value,'/x/y')='y1' and
extractValue(x.object_value,'/x/z')='z1' for update;
no rows selected
select x.object_value
from xmltab x
where extractValue(x.object_value,'/x/y')='b1' for update;
OBJECT_VALUE
<x>
<y>b1</y>
<z>z1</z>
</x>
select x.object_value
from xmltab x
where extractValue(x.object_value,'/x/z')='z1' for update;
OBJECT_VALUE
<x>
<y>b1</y>
<z>z1</z>
</x>
The following one returns correct result !!
select x.object_value, extractValue(x.object_value,'/x/y'), extractValue(x.object_value,'/x/z')
from xmltab x
where extractValue(x.object_value,'/x/y')='b1' and
extractValue(x.object_value,'/x/z')='z1' ;
OBJECT_VALUE
EXTRACTVALUE(X.OBJECT_VALUE,'/x/y')
EXTRACTVALUE(X.OBJECT_VALUE,'/x/z')
<x>
<y>b1</y>
<z>z1</z>
</x>
b1
c1
I get expected result for all the cases if the table is created in the following way
create table xmltab of XMLType;
Can anyone tell me why does select for update behaves in this strange way for binary xml table?Sorry for copy paste problem. b1 should be replaced with y1 and c1 with z1.
Here is the correct code.
create table xmltab of XMLType XMLTYPE store as binary xml;
Table created.
insert into xmltab values('<x><y>y1</y><z>z1</z></x>');
1 row created.
select x.object_value
from xmltab x
where extractValue(x.object_value,'/x/y')='y1' and
extractValue(x.object_value,'/x/z')='z1' ;
OBJECT_VALUE
<x>
<y>y1</y>
<z>z1</z>
</x>
The following query doesn't return any row!!
select x.object_value
from xmltab x
where extractValue(x.object_value,'/x/y')='y1' and
extractValue(x.object_value,'/x/z')='z1' for update;
no rows selected
select x.object_value
from xmltab x
where extractValue(x.object_value,'/x/y')='y1' for update;
OBJECT_VALUE
<x>
<y>y1</y>
<z>z1</z>
</x>
select x.object_value
from xmltab x
where extractValue(x.object_value,'/x/z')='z1' for update;
OBJECT_VALUE
<x>
<y>y1</y>
<z>z1</z>
</x>
The following one returns correct result !!
select x.object_value, extractValue(x.object_value,'/x/y'), extractValue(x.object_value,'/x/z')
from xmltab x
where extractValue(x.object_value,'/x/y')='y1' and
extractValue(x.object_value,'/x/z')='z1' ;
OBJECT_VALUE
EXTRACTVALUE(X.OBJECT_VALUE,'/x/y')
EXTRACTVALUE(X.OBJECT_VALUE,'/x/z')
<x>
<y>y1</y>
<z>z1</z>
</x>
y1
z1
I get expected result for all the cases if the table is created in the following way
create table xmltab of XMLType;
Can anyone tell me why does select for update behaves in this strange way for binary xml table? -
I'm trying to issue a SELECT ... FROM ... FOR UPDATE, and under specific verified conditions runs an UPDATE (where the current is positioned!).
The error code I get is:
ORA-01002: Fetch out of sequence.
Here you are my code:
/////////////////////START
import java.sql.*;
import oracle.jdbc.*;
import oracle.sql.*;
public class SelForUpdDin{
static{
try{
Class.forName("oracle.jdbc.driver.OracleDriver");
catch(Exception e){e.printStackTrace();}
// Queries and cursor name
public static void main (java.lang.String[] args){
String cursorName = null;
int codice = 0;
String cognome = null;
String job = null;
int manager = 0;
java.sql.Date dataAss = null;
int salario = 0;
int commissioni = 0;
int reparto = 0;
String rowid = null;
String sqlSelect = "SELECT empno, ename, "+
"job, mgr, hiredate, sal, comm, deptno, ROWID "+
"FROM scott.emp FOR UPDATE";
String sqlUpdate = "UPDATE scott.emp SET comm = ? WHERE ROWID = ? ";
try {
Connection con = DriverManager.getConnection("jdbc:Oracle:oci8:@","system","manager");
// Esecuzione della SELECT e produzione del RESULT SET
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(sqlSelect);
PreparedStatement ps = con.prepareStatement(sqlUpdate);
while (rs.next()) {
codice = rs.getInt(1);
cognome = rs.getString(2);
job = rs.getString(3);
manager = rs.getInt(4);
dataAss = rs.getDate(5);
salario = rs.getInt(6);
commissioni = rs.getInt(7);
reparto = rs.getInt(8);
rowid = rs.getString(9);
// Applicazione della business logic
if (reparto == 30)
{ System.out.println (cognome + " in dept= "+ reparto +
" with salary=" + salario + " has a commission= " +
commissioni);
int newcomm = 5555;
ps.setInt(1,newcomm);
ps.setString(2,rowid);
ps.executeUpdate();
else
{ System.out.println (cognome + " in dept= "+ reparto +
" with salary=" + salario + " has a commission= " + commissioni);
} // if - else
} // end while
rs.close();
ps.close();
stmt.close();
catch(Exception e)
e.printStackTrace();
} // end main()
} // end class
//PS.
//Many thanks to Bachar and Elangovan that ansewerd me to my previous posting and addressed me towards the right solutionHi
The documentation gives following explanation for the error :
ORA-01002 fetch out of sequence
Cause: In a host language program, a FETCH call was issued out of sequence. A successful parse-and-execute call must be issued before a fetch. This can occur if an attempt was made to FETCH from an active set after all records have been fetched. This may be caused by fetching from a SELECT FOR UPDATE cursor after a commit. A PL/SQL cursor loop implicitly does fetches and may also cause this error.
Action: Parse and execute a SQL statement before attempting to fetch the data.
In your program you should set auto commit to false as follows :
con.setAutoCommit(false);
Do this before executing the SELECT FOR UPDATE sql query.
At the end of program you can commit to save the updations as follows:
con.commit();
This should solve the problem.
Chandar -
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. -
SELECT FOR UPDATE via KODO queries
I want to do the following in a transaction:
1) SELECT * from Foo where type='x' FOR UPDATE
2) UPDATE Foo set sequence='22' where type='x'
3) commit
The issue: is there any way to force KODO to add the 'for update' in a find query.
ThanksPlease try kodo.LockManager configuration property.
-pessimistic: This is an alias for the kodo.jdbc.kernel.PessimisticLockManager , which uses SELECT FOR UPDATE statements (or the database's equivalent) to lock the database rows corresponding to locked objects. This lock manager does not distinguish between read locks and write locks; all locks are write locks.
Also please make sure you have following setting
kodo.jdbc.DBDictionary: SupportsSelectForUpdate=true
Please check kodo doc section 9.4.4.
JPA looks like
<property name="kodo.LockManager" value="pessimistic(VersionCheckOnReadLock=true,VersionUpdateOnWriteLock=true)"/>
JDO looks like
kodo.LockManager: pessimistic(VersionCheckOnReadLock=true,VersionUpdateOnWriteLock=true)
Thanks,
Yun -
Select for update gives wrong results. Is it a bug?
Hi,
Select for update gives wrong results. Is it a bug?
CREATE TABLE TaxIds
TaxId NUMBER(6) NOT NULL,
LocationId NUMBER(3) NOT NULL,
Status NUMBER(1)
PARTITION BY LIST (LocationId)
PARTITION P111 VALUES (111),
PARTITION P222 VALUES (222),
PARTITION P333 VALUES (333)
ALTER TABLE TaxIds ADD ( CONSTRAINT PK_TaxIds PRIMARY KEY (TaxId));
CREATE INDEX NI_TaxIdsStatus ON TaxIds ( NVL(Status,0) ) LOCAL;
Insert into TAXIDS (TAXID, LOCATIONID, STATUS) Values (100101, 111, NULL);
Insert into TAXIDS (TAXID, LOCATIONID, STATUS) Values (100102, 111, NULL);
Insert into TAXIDS (TAXID, LOCATIONID, STATUS) Values (100103, 111, NULL);
Insert into TAXIDS (TAXID, LOCATIONID, STATUS) Values (100104, 111, NULL);
Insert into TAXIDS (TAXID, LOCATIONID, STATUS) Values (200101, 222, NULL);
Insert into TAXIDS (TAXID, LOCATIONID, STATUS) Values (200102, 222, NULL);
Insert into TAXIDS (TAXID, LOCATIONID, STATUS) Values (200103, 222, NULL);
--Session_1 return TAXID=100101
select TAXID from TAXIDS where LOCATIONID=111 and NVL(STATUS,0)=0 AND rownum=1 for update
--Session_2 waits commit
select TAXID from TAXIDS where LOCATIONID=111 and NVL(STATUS,0)=0 AND rownum=1 for update
--Session_1
update TAXIDS set STATUS=1 Where TaxId=100101;
commit;
--Session_2 return 100101 opps!?
--Session_1 return TAXID=100102
select TAXID, STATUS from TAXIDS where LOCATIONID=111 and NVL(STATUS,0)=0 AND rownum=1 for update
--Session_2 waits commit
select TAXID, STATUS from TAXIDS where LOCATIONID=111 and NVL(STATUS,0)=0 AND rownum=1 for update
--Session_1
update TAXIDS set STATUS=1 Where TaxId=100102;
commit;
--Session_2 return 100103This is a bug. Got to be a bug.
This should be nothing to do with indeterminate results from ROWNUM, and nothing to do with read consistency at the point of statement start time in session2., surely.
Session 2 should never return 100101 once the lock from session 1 is released.
The SELECT FOR UPDATE should restart and 100101 should not be selected as it does not meet the criteria of the select.
A statement restart should ensure this.
A number of demos highlight this.
Firstly, recall the original observation in the original test case.
Setup
SQL> DROP TABLE taxids;
Table dropped.
SQL>
SQL> CREATE TABLE TaxIds
2 (TaxId NUMBER(6) NOT NULL,
3 LocationId NUMBER(3) NOT NULL,
4 Status NUMBER(1))
5 PARTITION BY LIST (LocationId)
6 (PARTITION P111 VALUES (111),
7 PARTITION P222 VALUES (222),
8 PARTITION P333 VALUES (333));
Table created.
SQL>
SQL> ALTER TABLE TaxIds ADD ( CONSTRAINT PK_TaxIds PRIMARY KEY (TaxId));
Table altered.
SQL>
SQL> CREATE INDEX NI_TaxIdsStatus ON TaxIds ( NVL(Status,0) ) LOCAL;
Index created.
SQL>
SQL>
SQL> Insert into TAXIDS (TAXID, LOCATIONID, STATUS) Values (100101, 111, NULL);
1 row created.
SQL> Insert into TAXIDS (TAXID, LOCATIONID, STATUS) Values (100102, 111, NULL);
1 row created.
SQL> Insert into TAXIDS (TAXID, LOCATIONID, STATUS) Values (100103, 111, NULL);
1 row created.
SQL> Insert into TAXIDS (TAXID, LOCATIONID, STATUS) Values (100104, 111, NULL);
1 row created.
SQL> Insert into TAXIDS (TAXID, LOCATIONID, STATUS) Values (200101, 222, NULL);
1 row created.
SQL> Insert into TAXIDS (TAXID, LOCATIONID, STATUS) Values (200102, 222, NULL);
1 row created.
SQL> commit;
Commit complete.
SQL> Original observation:
Session1>SELECT taxid
2 FROM taxids
3 WHERE locationid = 111
4 AND NVL(STATUS,0) = 0
5 AND ROWNUM = 1
6 FOR UPDATE;
TAXID
100101
Session1>
--> Session 2 with same statement hangs until
Session1>BEGIN
2 UPDATE taxids SET status=1 WHERE taxid=100101;
3 COMMIT;
4 END;
5 /
PL/SQL procedure successfully completed.
Session1>
--> At which point, Session 2 returns
Session2>SELECT taxid
2 FROM taxids
3 WHERE locationid = 111
4 AND NVL(STATUS,0) = 0
5 AND ROWNUM = 1
6 FOR UPDATE;
TAXID
100101
Session2>There's no way that session 2 should have returned 100101. That is the point of FOR UPDATE. It completely reintroduces the lost UPDATE scenario.
Secondly, what happens if we drop the index.
Let's reset the data and drop the index:
Session1>UPDATE taxids SET status=0 where taxid=100101;
1 row updated.
Session1>commit;
Commit complete.
Session1>drop index NI_TaxIdsStatus;
Index dropped.
Session1>Then try again:
Session1>SELECT taxid
2 FROM taxids
3 WHERE locationid = 111
4 AND NVL(STATUS,0) = 0
5 AND ROWNUM = 1
6 FOR UPDATE;
TAXID
100101
Session1>
--> Session 2 hangs again until
Session1>BEGIN
2 UPDATE taxids SET status=1 WHERE taxid=100101;
3 COMMIT;
4 END;
5 /
PL/SQL procedure successfully completed.
Session1>
--> At which point in session 2:
Session2>SELECT taxid
2 FROM taxids
3 WHERE locationid = 111
4 AND NVL(STATUS,0) = 0
5 AND ROWNUM = 1
6 FOR UPDATE;
TAXID
100102
Session2>Proves nothing, Non-deterministic ROWNUM you say.
Then let's reset, recreate the index and explicity ask then for row 100101.
It should give the same result as the ROWNUM query without any doubts over the ROWNUM, etc.
If the original behaviour was correct, session 2 should also be able to get 100101:
Session1>SELECT taxid
2 FROM taxids
3 WHERE locationid = 111
4 AND NVL(STATUS,0) = 0
5 AND taxid = 100101
6 FOR UPDATE;
TAXID
100101
Session1>
--> same statement hangs in session 2 until
Session1>BEGIN
2 UPDATE taxids SET status=1 WHERE taxid=100101;
3 COMMIT;
4 END;
5 /
PL/SQL procedure successfully completed.
Session1>
--> so session 2 stops being blocked and:
Session2>SELECT taxid
2 FROM taxids
3 WHERE locationid = 111
4 AND NVL(STATUS,0) = 0
5 AND taxid = 100101
6 FOR UPDATE;
no rows selected
Session2>Of course, this is how it should happen, surely?
Just to double check, let's reintroduce ROWNUM but force the order by to show it's not about read consistency at the start of the statement - restart should prevent it.
(reset, then)
Session1> select t.taxid
2 from
3 (select taxid, rowid rd
4 from taxids
5 where locationid = 111
6 and nvl(status,0) = 0
7 order by taxid) x
8 , taxids t
9 where t.rowid = x.rd
10 and rownum = 1
11 for update of t.status;
TAXID
100101
Session1>
--> Yes, session 2 hangs until...
Session1>BEGIN
2 UPDATE taxids SET status=1 WHERE taxid=100101;
3 COMMIT;
4 END;
5 /
PL/SQL procedure successfully completed.
Session1>
--> and then
Session2> select t.taxid
2 from
3 (select taxid, rowid rd
4 from taxids
5 where locationid = 111
6 and nvl(status,0) = 0
7 order by taxid) x
8 , taxids t
9 where t.rowid = x.rd
10 and rownum = 1
11 for update of t.status;
TAXID
100102
Session2>Session 2 should never be allowed to get 100101 once the lock is released.
This is a bug.
The worrying thing is that I can reproduce in 9.2.0.8 and 11.2.0.2. -
Select for update that doesn't return any rows
Are there any odd side-effects that may occur if a select for update that returns no results is never committed? I wouldn't think there are, but I'm not sure if there would be some kind of overhead or unforeseen consequences. This isn't a terribly important question, but it's come up in some coding I've done and I've not been able to find any documentation addressing it.
A select for update only locks rows that meet the predicate specified in the where clause. So, if the query returns no rows, no rows are locked.
session1> SELECT * FROM t;
ID DESCR
1 Un
5 One
2 THIS IS WA
session1> SELECT * FROM t
2 WHERE id = 11 FOR UPDATE;
no rows selectedA second session can update rows in the table
session2> UPDATE t
2 SET descr = 'One'
3 WHERE id = 1;
1 row updated.John
Edited by: John Spencer on Jan 7, 2009 1:36 PM
I just realized that, although you can do updates on the table after the select fo update that returns no rows, you cannot do DDL operations liike a truncate. Unless the session that does the select for update either ends the transaction (i.e. commit or rollback) or ends the session DDL operations will fail. -
Memory Leak - select for update
Hi All.
Doing an application using OCI 8.1.7 I faced with a memory leak. (or it seems to). The leak is caused by OCIStmtExecute with SELECT FOR UPDATE statement when the iters parameter of that function is 0. In all other cases it works Ok. Below you can find a code causes a leak:
const char* sqlStatement = "select integercol from test_types for update";
OCIStmt* ociStatementHandle = 0;
OCIHandleAlloc(ociEnvHandle,(dvoid **)&ociStatementHandle,
OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0));
OCIStmtPrepare(ociStatementHandle, ociErrorHandle,
(text*)sqlStatement, strlen(sqlStatement), OCI_NTV_SYNTAX, OCI_DEFAULT));
int int_test;
OCIDefine* ociDefineHandle = 0;
OCIDefineByPos(ociStatementHandle, &ociDefineHandle, ociErrorHandle,
1, (dvoid *)&int_test, (sword) sizeof(int), SQLT_INT, (dvoid *) 0, (ub2 *)0,
(ub2 *)0, OCI_DEFAULT));
ub4 iters = 0; // (0 causes a leak)
for( int i=0; i < 100000; i++ )
OCIStmtExecute(ociServiceHandle, ociStatementHandle, ociErrorHandle, iters, (ub4) 0, (CONST OCISnapshot *) NULL, (OCISnapshot *) NULL, OCI_DEFAULT));
If I change iter to 1 the leak disappears, but it is not suitable of course. Oracle documentation says following:
iters (IN)
For non-SELECT statements, the number of times this statement is executed is equal to iters - rowoff.
For SELECT statements, if iters is non-zero, then defines must have been done for the statement handle. The execution fetches iters rows into these predefined buffers and prefetches more rows depending upon the prefetch row count. If you do not know how many rows the SELECT statement will retrieve, set iters to zero.
This function returns an error if iters=0 for non-SELECT statements.
Did somebody face the problem? Do you know how to fix it?
null<BLOCKQUOTE><font size="1" face="Verdana, Arial, Helvetica">quote:</font><HR>Originally posted by Bjorn Engsig ([email protected]):
Are you saying, that the memory leak disappears if you don't do 'for update' in the query?
Also, is the memory leak on the client or server side?<HR></BLOCKQUOTE>
Yes, the leak appeares ONLY for 'select ... for update' statements.
It is a client side leak, the client is Win2000.
null -
Hi there
when I do a simple select statement like
select * from table
I recieve all the records without a problem
when I add 'for update' like
select * from table for update
this seems to take a long time (I don't actually get a result)
Is there something I'm doing wrong or have I incorrectly set up my oracle server?As you are saying that your normal query is running fine but if you are using query with for update of it takes more time than previous.
But it is normal behaviour of the oracle itself, when you use for update of, oracle put lock on selected row and then dont allow other users to access it unless and untill first user finish the desired task on selected row. It creates delay in response of your for update query.
null
Maybe you are looking for
-
Print a file to printer wirelessly and without need to use CD drive to install driver?
I have a HP-P1006 printer in my conference room and sometimes my guest want to send print to my printer and I have to connect their laptop with USB cable to my printer and install printer driver thought CD Drive. I want to know if there is a way to p
-
My phone changed the screen to the apple logo and kind of 'reboot it self' by it self
So I was on my phone on Safari and all of a sudden , the screen freezes. I tapped it a couple times and nothing happened. Then, in a matter of a couple seconds, my iPhone 4 changes the screen to the apple logo(the black background and the apple logo
-
Release of Locks for SEM Planning Layouts in EP
Hi, We are using SEM Web Layouts and they are being displayed through the SAP Enterprise Portal. To avoid messages when navigating between layouts, we have set the Independant Application Flag to False in the Web Layout Customising, however this is c
-
J2re 1.4.2_12 permissions issue?
Our users do not have admin rights. I installed 1.4.2_12 as local administrator. When we bring up our webpage, java is not detected under a regular user. Login as an administrator and it detect just fine. All other versions do not have this problem.
-
My Nef files will not open in Adobe Bridge after downloading from Nik Transfer and View NX. I have a new Imac just setting up and transferred all my files to new computer. All previous raw files are not opened either but downloaded.