4 Replies Latest reply on Apr 1, 2013 2:37 AM by bondchan921

    Optimistic Locking and Transaction Setup

    ppetrou

      Hi,

      I think this is a very simple issue but I am getting confused.

      I have a form in a web application which displays data and the user
      edits them. I use optimistic locking using the version lock strategy
      which seems to work fine as the version_lock column increments
      after each commit.

      I have a stateless session bean with a method that retrieves the value object (CMP Entity Bean) and populates the form.
      Then another method in the session bean does the update after the user
      clicks save changes. Both methods and the entity bean
      are marked as Required in the ejb-jar.xml

      My problem is that these two methods are 2 different transactions so
      JBoss does not detect the update of the data when 2 users update the
      form concurrently and no exception from the optimistic locking mechanism is thrown.

      The only way I can think is with client-initiated transaction which
      begins before the retrieval of the data and commits after the user clicks
      save.

      Is there a better way to implement this using XML declarations?
      I just need to include the user input (thinking time) inside the transaction.

      Thanks

      Petros

        • 1. Re: Optimistic Locking and Transaction Setup
          ppetrou

          Here is some code to make my enquiry more clear.

          The version_lock optimistic strategy in JBoss 4.0.0 has been setup
          correctly as the version_lock field autoincrements after every commit.
          Both the session bean and the entity bean are marked as Required
          in the ejb-jar.xml.

          My main question is if this is the correct way to implement optimistic
          locking with JBoss. I cannot think of another way other than client
          initiated transaction to include the
          user input time inside the same transaction where
          the retrieval and save of the data takes place.

          If I remove the userTrans.begin and .commit statements JBoss
          never throws the following exception when 2 users edit the same record.

          org.jboss.tm.JBossRollbackException: Unable to commit, tx=TransactionImpl:XidImpl[FormatId=257, GlobalId=c1700p/14, BranchQual=, localId=14] status=STATUS_NO_TRANSACTION; - nested throwable: (javax.ejb.EJBException: Update failed. Expected one affected row: rowsAffected=0, id=10)


          Client Code
          (I want to make a web application but I use this
          simple command line application to demonstrate my problem)


          
          UserTransaction userTran = (UserTransaction)ctx.lookup("UserTransaction");
          
          userTran.begin();
          
          mySessionBean aSessionBean = aSessionHome.create();
          PersonData data = aSessionBean.retrieve(); // Getting the value object
          
          System.out.println("This is the information requested:");
          System.out.println(data);
          System.out.println("Please edit the name:");
          
          data.setName(buf.readLine());
          aSessionBean.updatePerson(data);
          
          userTran.commit();
          
          



          jboss.xml

          <container-configurations>
           <container-configuration extends="Instance Per Transaction CMP 2.x EntityBean">
           <container-name>Optimistic CMP EntityBean</container-name>
           <locking-policy>org.jboss.ejb.plugins.lock.JDBCOptimisticLock</locking-policy>
           </container-configuration>
           </container-configurations>



          jbosscmp-jdbc.xml

          <optimistic-locking>
           <version-column/>
           <field-name>version_lock</field-name>
           <column-name>VERSION_LOCK</column-name>
           </optimistic-locking>




          • 2. Re: Optimistic Locking and Transaction Setup
            aloubyansky

            That's right since entity beans can't be detached/reattached to a transaction. All the work must be done in the same tx.

            • 3. Re: Optimistic Locking and Transaction Setup

              I don't understand why you need any user transaction.

              If you are using a value object that contains the version number, doesn't it go like this:

              TX1 and TX2 both retrieve value object and use it in a web form.

              User 1 and User 2 make independent changes.

              User 1 commits, via a session bean method which requires a transaction.
              Entity is retrieved and update attempted.
              Commit works ok because version numbers match.
              Version number is incremented.

              User 2 commits, via same session bean method.
              Entity is retrieved and update attempted.
              Version number does not match, so exception is thrown and transaction rolls back.

              Why should any user transaction be required?

              • 4. Re: Optimistic Locking and Transaction Setup
                bondchan921

                for this error, I have done a serial of test, the following shows how this error is generated

                 

                t0: TX1, select  VERSION_LOCK as vl1, ID id1 from table;

                t1: TX2, select  VERSION_LOCK as vl2, ID id2 from table;  -- vl1 == vl2, and id1 = id2

                t2: TX1, update table set VERSION_LOCK = vl3, anotherfiled=... where VERSION_LOCK=vl1 and id = id1 --TX1 get database rowlock.

                t3: TX2, update table set VERSION_LOCK  = vl4, anotherfiled=... where VERSION_LOCK=vl2 and id = id2 --TX2 have to wait same rowlock

                t4: TX1, commit;       ----TX1 change VERSION_LOCK to vl3, and release rowlock

                                               --therefore TX2 can't locate one row by the where clause. so update sql return 0,

                                                --therefore EJB interceptor throw EjbException.