Is EJB read-only methods participating in transaction ?
jbjopi Feb 28, 2005 6:25 AMI 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.