Skip to Main Content

SQL & PL/SQL

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Interested in getting your voice heard by members of the Developer Marketing team at Oracle? Check out this post for AppDev or this post for AI focus group information.

select for update doesn't work for me

2923653Apr 2 2015 — edited Apr 7 2015

I have a table that stores a pool of numbers. These numbers once used, should not be used again within 365 days. On top of that, different processes requesting for a number should be allocated different numbers. Basically a number should be used only once.

Below is the code I used to allocate 100 numbers. It's supposed to select a row, try to lock it by using "FOR UPDATE". If able to select, I assume it's available and update the LASTMODTM. If unable to select, that means another process has locked it, and I will proceed to try the next number.

I executed 2 processes running the below code together, expecting that each process will get 2 unique sets of numbers, but I end up with exactly the same list of numbers for both processes. I believe the SELECT FOR UPDATE is not working, that's why both processes are able to select the same row. Any advice for me?

   DECLARE

      v_nbr NUMBER_POOL.NBR%TYPE := null;

      cnt INTEGER := 0;

      v_nbrlist VARCHAR2(32676) := '';

   BEGIN

      FOR x IN (

            SELECT ROWID RID

            FROM NUMBER_POOL

            WHERE

            AND SYSDATE - LASTMODTM > 365

            ORDER BY LASTMODTM, NBR

      )

      LOOP

         BEGIN

            --To lock the row so that it won't be allocated to other request

            SELECT MAWB

            INTO v_nbr

            FROM NUMBER_POOL

            WHERE ROWID = x.RID

            FOR UPDATE NOWAIT;

         EXCEPTION

            --Unable to lock row, that means this nbr is locked by another concurrent process. Try the next nbr

            WHEN OTHERS THEN

               CONTINUE;

         END;

        

         UPDATE NUMBER_POOL

         SET LASTMODTM = SYSTIMESTAMP

         WHERE ROWID = x.RID;

  

         cnt := cnt + 1;

         v_nbrlist := v_nbrlist || ',' || v_nbr;

        

         IF cnt = 100 THEN

            DBMS_OUTPUT.PUT_LINE(SUBSTR(v_nbrlist, 2));

            EXIT;

         END IF;

      END LOOP;

   END;

This post has been answered by unknown-7404 on Apr 6 2015
Jump to Answer
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on May 5 2015
Added on Apr 2 2015
15 comments
2,094 views