Processing SELECT FOR UPDATE queries

Hello,
Is there any occi sample code that uses "SELECT ... FOR UPDATE" and "WHERE CURRENT OF"?

I think "where current of" is not supported in OCI as well.
But, may be I can use the below steps for positioned updates using "select for ... updat" sqls
1. Lock the rows by executing the "select for ...update " SQL.
2. Get the result set
3. Now, as iterating the result set, get the current row id using ResultSet.getRowid() or getRowPosition() (I am not sure which one to use. But, I think getRowPosition() is suitable as it explicitly returns the rowid of the current row position)
4. Execute the update stmt "update tableName set ... where rowid=?"
5. Iterate the Result set and update the row as in pt. 4
6. commit the transaction (this unlocks the rows)
Please let me know if this is correct...

Similar Messages

  • 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 Light

    Thanks 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.

  • Select for update no wait polling strategy for an esb process

    I have an esb process which currently uses 'logicaldeletepolling strategy'.
    I need to change it to use the 'select for update no wait' distributed polling strategy.
    What steps do I need to perform on the existing process ?

    What do you mean by
    same record is opened Do you mean, queried by another form? This is not possible.... other session can always query a table (with approp privs)
    You are confusing me....
    1) you update DEPT using a form (not clear which one - but it is irrelevant)
    2) Another form is querying the DEPT table and you want to know this? Why? What do you care?
    If you are worried about a lost update, don't... Forms takes care of this

  • 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.
    Thanks

    Please 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

  • List current DML in DB including SELECT for Update

    In order to list all currently opened DML we can select v$open_cursor and link it to to v$SQL in order to retrieve the v$SQL.COMMAND_TYPE.
    All DML operation have the following number in v$sql.command_type :
    2 : 'INSERT'
    6 : 'UPDATE',
    7 : 'DELETE',
    189 : 'MERGE'
    But 'SELECT for update it is still 3 like any non regular SELECT.
    I did not found information in v$lock nor in v$transaction that would allow me
    to link an open cursor of type 3 (SELECT but in fact for update) to the opened transaction in v$transaction.
    Does anybody knows how to assert than a SELECT is in fact a DML short of grepping the 'FOR update' in the SQL text.
    Such an Horrible trick would force me to search all opened cursor text for each session with an entry in v$transaction.

    Thanks for replying.
    I could have had the usage of less aggressivity and more competences. You advice is simply stupid :
    -- seesion 1 :
    select * from toto where id = 20 for update ;
    select sid from v$mystat where rownum = 1 ;   -- > sid=1614
    -- session control : check v$transaction
    col version new_value version noprint
    col field new_value field noprint
    col used_urec format 999999 head 'Undo|Records'
    col undo_size head 'Undo|size (k)' justify c
    set lines 150
    select substr(version,1,instr(version,'.',1)-1) version from v$instance;
    select decode(&version,9,'','XID,') field from dual;
    Select r.segment_name,To_Char(To_Date(vt.Start_Time,'MM-DD-RR HH24:MI:SS'),'MM-DD HH24:MI:SS') strt
         ,  decode(vs.status,'ACTIVE',vs.last_Call_et,0) since , vs.sid, vs.status se_status,
           &field vt.status tr_status, log_io, phy_io,cr_get,cr_change, vt.used_urec, vt.used_ublk * p.value/1024 undo_size
      From dba_rollback_segs dr,
           v$rollstat rs,
           v$transaction vt,
           v$session vs,
           v$process vp,
           dba_rollback_segs r,
           v$parameter p
      Where vs.Paddr = vp.Addr (+) AND p.name  = 'db_block_size'
       and vt.xidusn (+)  = r.segment_id
       And vs.UserName Is Not Null
       And vs.Taddr Is Not Null
       And vs.Taddr = vt.Addr
       And vt.xidusn = dr.segment_id
       And vt.xidusn = rs.usn
        Order By VS.OsUser, To_Date(vt.Start_Time,'MM-DD-RR HH24:MI:SS') ;
                                   Running        Session                   Transact                                                Undo    Undo
    SEGMENT_NAME Start time       time (s)    SID Status   XID              Status       LOG_IO     PHY_IO     CR_GET  CR_CHANGE Records  size (k)
    _SYSSMU21$   04-13 11:02:24          0   1614 INACTIVE 0015002A0003A800 ACTIVE            3          0        104          0       1          8
    -- so we have a transaction in 1614. Let's retrieve its SQL :
    -- session control : what do we have in  v$session :
      1  select sql_hash_value, b.sql_text sql_text, prev_hash_value , bb.sql_text prev_sql_text
      2    from
      3       v$session  a, v$sql b, v$sql bb
      4  where sid = 1614
      5    and a.sql_hash_value = b.hash_value (+)
      6*   and a.prev_hash_value = bb.hash_value (+)
    SQL> /
    SQL_HASH_VALUE SQL_TEXT                                      PREV_HASH_VALUE PREV_SQL_TEXT
                 0                                                     897388722 select sid from v$mystat where rownum = 1
    -- gone !
    -- Conclusion : joining v$session to v$transaction is useless if you want to retrieve the SQL in system currently opened.
    -- moreover, if  start a transaction with many queries, you are still limited to 2 slot in v$session.

  • 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!

  • JDBC SELECT FOR UPDATE

    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 solution

    Hi
    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

  • LOCK TABLE vs select for update

    Hello All,
    if the requirement is to lock an entire huge table to prevent any users from performing any update statement, which statement has more performance gain and why: LOCK TABLE or select fro update nowait?
    is there any overhead of using LOCK TABLE statement?
    Thanks,

    The reason I said to revoke update privilege is because I do not understand the requirement. Why do you want to prevent users from updating the table? I am assuming that users should never be allowed to update the table. In that case locking the table and select for update would be no good. If you want to stop users from updating while some one else is updating, why? All the lock table or select for update will do is cause their session to wait (hang) until the locking process commits or rolls back. This could generate a few (sic) complaints that the user application is slow/freezing.
    If you can state the business problem, perhaps we can offer a solution.

  • 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 Oliveira

    First, 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

  • Database select for update locks ADF

    Hi,
    When a user has initiated an update session in an adf application and locking is optimistic it will acquire a lock on table row using select for update no wait; . But when the user closes a tab the session would not be terminated. Now i know as HTTP is a stateless protocol, we can wait for the timeout and then the lock will be released using a session listener implementation. But if the user instead tries to log in again in a new tab and tries to edit the same record he will receive a message stating that another user already holds a lock on the record which is correct, but is misleading.
    So can we rely on javascript for these scenarios that as soon as the user closes the tab the session should be terminated.
    Here's a snippet
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/dojo/1.4/dojo/dojo.xd.js" ></script>
    <script type="text/javascript">
    var unLoad = function() {
        dojo.io.script.get({
        url:'http://127.0.0.1:7101/myapp/adfAuthentication?logout=true',
        timeout:15000,
      dojo.addOnWindowUnload(unLoad);
    </script>I know this might not work always as it depends on the fact that request might / might not be processed by the server.
    Are there any alternate solutions and also reducing the session timeout is ruled out in my scenario.

    Ramandeep,
    So are there other alternatives or solutionsAlternatives or solutions to what, exactly? As Jobinesh has told you, as long as you use optimistic locking, ADF doesn't acquire database locks except in the context of a transaction that is going to be completed in the current HTTP request. You could obviously force ADF to deviate from this if you called "postChanges" during an HTTP request and leave the transaction hanging, but that would just be wrong in an optimistic locking scenario - the solution would be "don't do that."
    John

  • Updatable View issues:  cannot select FOR UPDATE from view with DI

    Hi All,
    I have a simple view XY and an instead of trigger on that to insert data into one table which is used in the my view. When I do insert statement on view XY it is working fine from sql but when i used same thing with page process of " Process Row of XY Automatic Row Processing (DML) " i am getting following error. I am using APEX 3.0 . Please help me.
    ORA-20001: Error in DML: p_rowid=xxxx, p_alt_rowid=abc, p_rowid2=, p_alt_rowid2=. ORA-02014: cannot select FOR UPDATE from view with DISTINCT, GROUP BY, etc.
    Thanks

    James,
    are you already on 3.0.1.00.07 or 3.0.1.00.08? Have a look at the release notes, it says something about a bug fix for some occurrences of ORA-02014.
    Also have a look at the new substitution value/item FSP_DML_LOCK_ROW which turns locking off if you set it to FALSE. See http://www.oracle.com/technology/products/database/application_express/html/3.0.1_readme.html#CHDIDIAF and also http://download-west.oracle.com/docs/cd/B32472_01/doc/appdev.300/b32471/advnc.htm#BCGFDAIJ
    Patrick
    My APEX Blog: http://inside-apex.blogspot.com
    The ApexLib Framework: http://apexlib.sourceforge.net
    The APEX Builder Plugin: http://apexplugin.sourceforge.net/ New!

  • Select for update no wait distributed polling strategy

    I have an esb process which currently uses 'logicaldeletepolling strategy'.
    I need to change it to use the 'select for update no wait' distributed polling strategy.
    What steps do I need to perform on the existing process ?

    Hi,
    Try: http://download-east.oracle.com/docs/cd/B31017_01/integrate.1013/b28994/adptr_db.htm#sthref558 (Oracle® Application Server Adapters for Files, FTP, Databases, and Enterprise Messaging User's Guide
    10g Release 3 (10.1.3.1.0)
    Part Number B28994-02).
    Also you can reconfigure DB adapter (I think this's the best way): laucnch adapter configuration wizard in JDev and at step 9 (adapter options) check distributed polling checkbox (query now contains for update clause).

  • 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&#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....

  • "All of the Playlists Selected for Updating No Longer Exist"

    My family has 2 ipod shuffles. After purchasing a Nano recently, I inserted the cd that came with it. Apparently the existing iTunes software was removed and reinstalled. At any rate, the library still shows all the original songs, but when the Nano is plugged in, iTunes immediately gives a prompt stating "Songs on the iPod *** cannot be updated because all of the playlists selected for updating no longer exist." The library is there, the playlists that were there are there, and I can play the songs on my cpu. Is there anything I can do besides completely uninstalling everything and starting over?
    iPod Nano   Windows XP Pro  

    This user tip should help you sort out your missing playlist problem: Hudgie - iPod cannot sync because one or more playlists are missing

Maybe you are looking for