5 Replies Latest reply on Mar 11, 2010 10:18 AM by cwinfrey

    not seeing default QueuedPessimisticEJBLock behavior

      In the JBoss reading that I have done, the JBoss application server uses a transaction lock to ensure that there is only one active instance of a given entity bean (one with a given primary key) in memory at one time.  If any method at all is invoked on an entity bean within a transaction, no other transaction can have access to this bean until the holding transaction commits or is rolled back.

       

      In my testing I am not seeing this behavior.  The testing results are consistent with no transaction lock ever being placed.  I am hoping that someone can suggest why - and how I can get the default behavior.

       

      Summary of environment:
      * JBoss 5.1.0.GA server/default + Oracle datasource
      * Oracle 10g
      * EJB 3 Entity Beans with CMP

       

      The Entity Beans do not use any custom primary key classes.  A Java Long is used for all primary keys.  No equals or hashCode method overrides exist.  standardjboss.xml has not been modified and no custom container-configurations are implemented. There is no explicit mapping of the entity beans to a container configuration -- JBoss default determination of entity bean to container configuration is used.  This should be a container with commit option B and QueuedPessimisticEJBLock.

       

      Summary of test:
      Command-line client program accesses a stateless session bean remote interface to execute the test method (executeConcurrencyTest) to update an Entity Bean (Person).

       

      executeConcurrencyTest outline:
      * retrieve a Person using EntityManager.find(Person.class, <primary key value>)
      * update a field in the record
      * (optionally) pause processing for ~1 minute using an ldap retrieval that happens to be very slow
      * return from method

       

      Two overlapping test runs, using the same Person primary key, are executed as follows:
      * Start Run#1 with the optional pause selected.
      * Wait until logging indicates that Run #1 is "pausing".
      * Start run#2 without the optional pause.
      * Run#2 completes successfully and its update is seen via SQLDeveloper.
      * Run#1 completes successfully and its update is seen via SQLDeveloper.

       

      What was expected is that run#2 would block at the EntityManager.find until run#1 transaction completed at the method return, because of a JBoss transaction lock, but this did not happen.

       

      Trace-level logging during test runs does not show any entries for EntityLockInterceptor, which is responsible for scheduling any locks that must be acquired.  Of course, this could just mean that no trace-level logging is included in the java code.

       

      EntityLockMonitor service is enabled for jmx-console.  Neither listMonitoredBeans nor printLockMonitor show any entries at all during the test runs.  AverageContenders, MedianWaitTime, and MaxContenders are always zero.

        • 1. Re: not seeing default QueuedPessimisticEJBLock behavior
          whitingjr

          Hi,
            Pessimistic locking behaviour your expecting to see does not occur by default. Instead optimistic locking is used to minimise deadlocking in applications.

          To achieve what your attempting use the EntityManager.lock(Object, LockModeType) method in your first EJB. With a LockModeType.READ.


          http://java.sun.com/javaee/5/docs/api/javax/persistence/EntityManager.html#lock(java.lang.Object,%20javax.persistence.LockModeType)


          For future reference, EJB3 questions should be posted to the EJB user list.
          http://community.jboss.org/en/ejb3?view=discussions

          Jeremy

          • 2. Re: not seeing default QueuedPessimisticEJBLock behavior

            I think my EJB 3.0 entity bean should map to the container-name 'Standard Pessimistic CMP 2.x EntityBean' in standardjboss.xml.  This container uses locking-policy org.jboss.plugins.lock.QueuedPessimisticEJBLock and one of the interceptors is org.jboss.ejb.plugins.EntityLockInterceptor .  The JBoss Server documentation states:

             

            "Some form of application server level locking is needed for entity beans to provide the transaction isolation properties that you are used to with traditional databases. With the default configuration of JBoss there is only one active instance of a given entity bean in memory at one time.  This applies for every cache configuration and every type of commit-option. Entity bean locking is totally decoupled from the entity bean instance.  The logic for locking is totally isolated and managed in a separate lock object.  Because there is only one allowed instance of a given entity bean active at one time, JBoss employs two types of locks to ensure data integrity and to conform to the EJB spec.

             

            Method Lock: The method lock ensures that only one thread of execution at a time can invoke on a given Entity Bean.  This is required by the EJB spec.

             

            Transaction Lock: A transaction lock ensures that only one transaction at a time has access to a given Entity Bean.  This ensures the ACID properties at the application server level.  Since, by default, there is only one active instance of  any given Entity Bean at one time, JBoss must protect this instance from dirty reads and dirty writes.  So, the default entity bean locking behavior will lock an entity bean within a transaction until it completes.  This means that if any method at all is invoked on an entity bean within a transaction, no other transaction can have access to this bean until the holding transaction commits or is rolled back."

             

            The interceptor  org.jboss.ejb.plugins.EntityLockInterceptor is supposed to start the processing for this transaction lock.

             

            So I am confused.  Why is this transaction lock not the default behavior?

            • 3. Re: not seeing default QueuedPessimisticEJBLock behavior

              After some more reading, I may have the answer to my own question.  It seems that the container configurations in standardjboss.xml for entity beans (such as the 'Standard Pessmistic CMP 2.x EntityBean' container-configuration) are for EJB 2.x, not EJB 3.x.  So all the comments in JBoss documentation about the transaction lock apply to EJB 2.x entity beans.  As stated in the book "JBoss in Action" in reference to use of the jboss.xml deployment descriptor:

               

              "In JBoss AS, there's a container definition for each type of remotely accessible EJB. ... In EJB3, an entity manager can't be accessed remotely and isn't managed by a server container. ... Because entities aren't managed by a server container, as we explore the container configuration, you won't see anything relating to EJB3 entities."

               

              My testing is certainly consistent with this interpretation.

               

              Do you think this is correct?

              • 4. Re: not seeing default QueuedPessimisticEJBLock behavior
                whitingjr
                Hi,
                  I recommend you try posting your findings on the EJB3 forum because this topic is very specific to that domain.

                Jeremy
                • 5. Re: not seeing default QueuedPessimisticEJBLock behavior
                  Thanks, I have reposted this issue to the EJB3 forum.