1 Reply Latest reply on Mar 4, 2003 2:57 PM by Lars Bergmann

    synchronize find then create

    Chris Mactaggart Newbie

      I am having a problem with synchronization in my session bean. I first try to find an entity bean and if it doesn't exist then I create it. The problem arises when the methods are called at the same time by two clients.

      Client1 tries to find the entity - but doesn't find it
      Client2 tries to find the entity - but doesn't find it
      Client1 creates the entity successfully
      Client2 tries to create the entity but cant because it violates a primary key constraint

      Can I put the find and create in a synchronized block? Will this work in Clustering?

      What are my other options?

        • 1. Re: synchronize find then create
          Lars Bergmann Newbie



          Hi, we faced the same problem (excessive concurrent entity create -
          see http://www.jboss.org/modules/bb/index.html?module=bb&op=viewtopic&t=forums/ have three options:

          1. Running the create() within a tx you can catch DuplicateKeyException
          thrown by the second create(). (If you run outside a tx - you get some
          SQLException "PK-constraint violated...".)

          Retry findByPrimaryKey() once upon DuplicateKeyException will get you
          the valid instance. This works in a cluster. And it´s easy.

          2. This is the option we choose (for performance - we do not want to call
          findByPrimaryKey() twice since it´s a database call):

          Create and maintain a lock on the primary key of an entity type.
          I wrote an interceptor that catches a registerLock(PrimaryKey) method
          via home interface. This interceptor creates a lock for each PK.
          All subsequent threads requesting for this PK will be blocked until
          the first caller frees the lock.
          (Beware this lock must block all threads before any JBoss resources are
          involved; i.e. it´s the first interceptor in the chain.)

          3. Serialize access to your entity create via "Synchronized Singleton Stateless
          SessionBean" container configuration. Do not use any synchronize-code
          in your session bean - it won´t help anyway (you probably have two instances
          of that session bean accessing your entity concurrently).

          I´d choose the first option if you´re for a cluster (else you would need to
          distribute the lock).

          The second option is very efficient on a single node and more generic
          (you can have the lock spanning multiple method invocations/tx independently
          from JBoss resource/tx management). But this should be a rare requirement...

          The third option is easy but introduces a bottleneck with the singleton - and we
          really do want to scale with J2EE?


          Lars