3 Replies Latest reply on Nov 25, 2005 4:42 AM by epbernard

    Concurrency in Transactions

    lipido

      Hello.

      I'm using Jboss4.0.3SP1 with MySQL 5. I'm newbie of course.

      I'm trying some concepts about concurrency in transactions. I've read that in EJB3 I should not be worried about this concepts. I have a table STUDENT with a "Name" field. I have a Stateless Session Bean with a method (I supose it's transactional (In fact, rollbacks when an exception is thrown works) ) that doesn't behaves as an atomic method:

      public @Stateless class StudentsManagerBean implements StudentsManager {

      @PersistenceContext
      private EntityManager manager;

      //@TransactionAttribute(TransactionAttributeType.REQUIRED)
      public void modifyStudent(){
      //manager.getTransaction().begin();

      Student toret = manager.find(Student.class, "a");
      toret.setName(toret.getNombre()+"_modified");

      try {
      System.out.println("Other request may arrive!!");
      Thread.sleep(10000);
      } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();

      }

      manager.flush();
      //manager.getTransaction().commit();
      }


      When I try to call this method from 2 clients in the follow manner:
      Client 1 calls modifyStudent()
      Client 1 gets the Student "a" from the database
      Client 1 modifies the field of the student
      Client 1 sleeps....
      Client 2 calls modifyStudent()
      Client 2 gets the Student "a" from the database
      Client 2 modifies the field of the student
      Client 2 sleeps....
      Client 1 finishes the transaction
      Client 2 finishes the transaction

      If the method is really atomic, the field "name" in the database must be "studentname_modified_modified" (with two append opperation), but I get "studentname_modified". This behaviour is a lost update. I'm thinking in a bank application with a method like "increaseMyMoneyIn1000", calling it twice I get only 1000 more!!

      I'm sure there is a simple solution. Any ideas?. I've trying with multiple variants (EXTENDED EntityManager, merge-flush, flush-merge) !!!!

        • 1. Re: Concurrency in Transactions
          bill.burke

          optimistic locking maybe your solution. Try adding a @Version field to your Studient entity class. Then client2 will be aborted.

          You would have to use the Hibernate APIs to perform a pessimistic lock.

          • 2. Re: Concurrency in Transactions
            lipido

            So, Do I have to use @Version in all Entities? Is there a performance/other kind of problem/drawback doing that?

            • 3. Re: Concurrency in Transactions
              epbernard

              The behavior you i've got is known as the secfond lost update issue.
              To solve that:
              - use repeteable read for your JDBC tx isolation level
              - or use read_commited + optimistic locking (ie @Version)

              @Version as no known drawbacks nor perf cost if you can afford adding a version column in your relational model