7 Replies Latest reply on Mar 14, 2005 2:33 AM by jbjopi

    Is EJB read-only methods participating in transaction ?

      I enjoy working with JBoss AS and would like to use the opportunity to say that it is a great product and all developers and supporters are doing a great job.

      My problem is that we get application deadlocks even though only methods marked for read-only in jboss.xml for my CMP EJB's are called.

      My setup to test the read-only functionality is the following:
      JBoss 3.2.7 on JVM 1.4.2 using XDoclet 1.2-beta3

      Statefull session bean S1 with CMT (container managed transactions) has two methods S1 and S2. Transactions for S1 and S2 are both set to "Required".

      I have a single CMP based EJB bean named E. All calls to this bean are going through the local home version!

      Client C1 makes a call to S1 at the same time as Client C2 is making a call to method S2. In order to test the read-only functionality sleeps are added to S1 and S2 ensuring that the following call sequence is executed:

      1. C1 call S1 which call read-only method M1 on bean A
      2. C2 call S2 which call read-only method M1 on bean B
      3. After a sleep C1 and still in method S1 obtains reference to bean B and call method M1. This causes C1 to become blocked waiting for C2 transaction to be completed
      4. C2 still in S2 now wake up and attempts to call method M1 on bean A which now results in an application deadlock exception.

      From my understanding of the read-only tag I would not expect an application deadlock in this case since calling read-only methods should not obtain a lock on the entity bean - or what ? I.e. step 3 in the call sequence should not block on the call to M1.

      My jboss.xml looks like the following for EJB E:

      <jboss>
       <enterprise-beans>
       <entity>
       <ejb-name>E</ejb-name>
       <local-jndi-name>local/E</local-jndi-name>
       <method-attributes>
       <method-name>get*</method-name>
       <read-only>true</read-only>
       </method-attributes>
       </entity>
       </enterprise-beans>
      </jboss>


      An outline of method S1 looks like the following (method S2 is similar just referencing entity B before entity A)

      /**
       * @ejb.interface-method
       * view-type="remote"
       * @ejb.transaction
       * type="Required"
       */
      public void S1() throws ServiceException {
       try {
       E entityA = getEntityById("76");
       String descA = entityA.getDescription();
      
       Thread.sleep(10000);
      
       E entityB = getEntityById("77");
       String descB = entityB.getDescription();
      
       Thread.sleep(10000);
       }
       catch (Exception e) {
       e.printStackTrace();
       throw new ServiceException(e);
       }
      }
      
      private E getEntityById (String id) throws NamingException, FinderException {
       // Get the operation home interface
       ELocalHome operationHome = EUtil.getLocalHome ();
      
       // Find the operation entity
       ELocal operationEntity = operationHome.findByPrimaryKey(id);
      
       // Return the operation entity found
       return operatioEntity;
      }
      


      Hope someone can help me out here. Probably I'm missing out on some of the JTA fundamentals, but I haven't been able to find an explanation for the results that I see anywhere else.



        • 1. Re: Is EJB read-only methods participating in transaction ?
          sviluppatorefico

          hi jbjobi........according me you'ld have to try the read-only tag on the hole entity. If in that manner it succeed, then maybe than the findByPrimaryKey method of your entity remains locked. Now I don't know if the find methods of an entity have a default read-only but I don't think it.

          • 2. Re: Is EJB read-only methods participating in transaction ?

            thanks for your answer sviluppatorefico.

            You are right about that I will not get any deadlock if the whole entity E is marked a read-only bean - but this of cause also prevents me from calling any set method on the bean which is not an option.

            I investigated further to check exactly where in step 3. C1 is becomming blocked. It is not on the findByPrimaryKey() as you suggest, rather it is on the call

            String descB = entityB.getDescription();


            or on entityB.M1() if I stick to my original description. So this again leads to my question: why is C1 getting blocked on a call to a read-only method ?

            • 3. Re: Is EJB read-only methods participating in transaction ?

              I forgot to inform you that I am using commit option A - if this in any way impacts the read-only functionality ?

              • 4. Re: Is EJB read-only methods participating in transaction ?
                sviluppatorefico

                the commit option A in a read-only entity bean cannot give deadlock problems. It tells that an entity bean never will refreshed since the developer wants it. Maybe a lock directly on the DataBase? what a DB do you use?

                • 5. Re: Is EJB read-only methods participating in transaction ?

                  I am using MS SQL Server 2000.
                  I have turned on the trace logging level for everything possible including org.apache and org.jboss and it shows that there is no SQL activity at all when step 3 is blocking on the call entityB.getDescription().

                  The following is the JVM Ctrl-break stack trace from the JBoss console window for the C1 thread - at the point in time where it is being blocked in step 3. I have underlined the two calls from my code respectively calling setTest1() and entityB.getDescription():

                  "RMI TCP Connection(22)-192.168.0.64" daemon prio=5 tid=0x039f4d78 nid=0xe00 in Object.wait() [4c3e000..4c3fd8c]
                   at java.lang.Object.wait(Native Method)
                   - waiting on <0x100ff328> (a org.jboss.ejb.plugins.lock.QueuedPessimisticEJBLock$TxLock)
                   at org.jboss.ejb.plugins.lock.QueuedPessimisticEJBLock.waitForTx(QueuedPessimisticEJBLock.java:332)
                   - locked <0x100ff328> (a org.jboss.ejb.plugins.lock.QueuedPessimisticEJBLock$TxLock)
                   at org.jboss.ejb.plugins.lock.QueuedPessimisticEJBLock.doSchedule(QueuedPessimisticEJBLock.java:236)
                   at org.jboss.ejb.plugins.lock.QueuedPessimisticEJBLock.schedule(QueuedPessimisticEJBLock.java:183)
                   at org.jboss.ejb.plugins.EntityLockInterceptor.invoke(EntityLockInterceptor.java:85)
                   at org.jboss.ejb.plugins.EntityCreationInterceptor.invoke(EntityCreationInterceptor.java:54)
                   at org.jboss.ejb.plugins.AbstractTxInterceptor.invokeNext(AbstractTxInterceptor.java:84)
                   at org.jboss.ejb.plugins.TxInterceptorCMT.runWithTransactions(TxInterceptorCMT.java:315)
                   at org.jboss.ejb.plugins.TxInterceptorCMT.invoke(TxInterceptorCMT.java:148)
                   at org.jboss.ejb.plugins.SecurityInterceptor.invoke(SecurityInterceptor.java:120)
                   at org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:191)
                   at org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor.invoke(ProxyFactoryFinderInterceptor.java:122)
                   at org.jboss.ejb.EntityContainer.internalInvoke(EntityContainer.java:484)
                   at org.jboss.ejb.Container.invoke(Container.java:723)
                   at org.jboss.ejb.plugins.local.BaseLocalProxyFactory.invoke(BaseLocalProxyFactory.java:359)
                   at org.jboss.ejb.plugins.local.EntityProxy.invoke(EntityProxy.java:44)
                   at $Proxy154.getDescription(Unknown Source)
                   at multiuser.services.basemodel.ejb.SProductionMgrEJB.setTest1(SProductionMgrEJB.java:437) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                   at java.lang.reflect.Method.invoke(Method.java:324)
                   at org.jboss.ejb.StatefulSessionContainer$ContainerInterceptor.invoke(StatefulSessionContainer.java:949)
                   at org.jboss.ejb.plugins.SecurityInterceptor.invoke(SecurityInterceptor.java:120)
                   at org.jboss.resource.connectionmanager.CachedConnectionInterceptor.invoke(CachedConnectionInterceptor.java:185)
                   at org.jboss.ejb.plugins.StatefulSessionInstanceInterceptor.invoke(StatefulSessionInstanceInterceptor.java:273)
                   at org.jboss.ejb.plugins.AbstractTxInterceptor.invokeNext(AbstractTxInterceptor.java:84)
                   at org.jboss.ejb.plugins.TxInterceptorCMT.runWithTransactions(TxInterceptorCMT.java:315)
                   at org.jboss.ejb.plugins.TxInterceptorCMT.invoke(TxInterceptorCMT.java:148)
                  


                  Someone with low level insight might be able to see from the stack trace why the QueuedPessimisticEJBLock is comming into action for a read-only bean eventually causing the thread to block ?

                  I am running with a fairly plain and normal JBoss setup so it really puzzles me that no one else is experiencing the same sort of problems :-)

                  • 6. Re: Is EJB read-only methods participating in transaction ?

                    Moderated: Ignored, CMP questions belong in the CMP forum not the JCA forum.

                    • 7. Re: Is EJB read-only methods participating in transaction ?

                      Adrian thanks for you reply, I'll try the CMP forum. The reason I posted it on the JCA forum is that it is also related to the transaction manager.