Reputation: 2484
Today I discovered some unexpected behaviour in EJB. I've got MDB with default transaction attribute (REQUIRED
) and SLSB with transaction attribute set to REQUIRES_NEW
. My MDB calls the SLSB and catch any exception that SLSB can throw. When something realy bad occurres in the SLSB and some subclass of RuntimeException
was thrown. Then new transaction, which was created for the SLSB, became marked for rollback. It is a correct behaviour from my point of view. Then MDB catch this exception and perform some action (write a message to log, for example) withour rethrow. But the MDB transaction somehow became marked for rollback too, which seems strange to me. Is this behaviour correct?
To be more precise I can write some code similar to actual one, that produce this behaviour:
@MessageDriven
public class A{
@EJB
private B b;
@Overried
public void onMessage(Message msg){
...
try{
b.process(msg);
} catch (Throwable t){
logger.error("Something gone wrong",t);
}
...
}
And SLSB looks like this:
@EJB
@Stateless
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public class B{
public void process(Message msg){
...
}
}
Problematic task flow looks like this:
onMessage(Message)
was called.B.process(Message)
method.B
occurred and RuntimeException
was thrown.RuntimeException
was wrapped in EJBException
and was successfully catched by message driven bean.onMessage(Message)
method was executed completely, but its transaction was marked for rollback.Can anybody explain this behaviour? Thanks in advance.
Upvotes: 2
Views: 4081
Reputation: 5813
As @gkuzmin stated.
The relevant part from section 13.3.7.1 from EJB 3.1 specfication:
If the bean class has superclasses, the following additional rules apply.
A transaction attribute specified on a superclass S applies to the business methods defined by S. If a class-level transaction attribute is not specified on S, it is equivalent to specification of TransactionAttribute(REQUIRED) on S.
A transaction attribute may be specified on a business method M defined by class S to override for method M the transaction attribute value explicitly or implicitly specified on the class S.
If a method M of class S overrides a business method defined by a superclass of S, the transaction attribute of M is determined by the above rules as applied to class S.
Note the bold part. It is not business method of a superclass of S as you can expected.
Upvotes: 2
Reputation: 2484
Solution to this problem was found. Actually TransactionAttribute
annotation was placed on abstract superclass of B
bean and was ignored. EJB runtime environment in WebLogic server ignores annotations from B
superclass and uses default REQUIRED
attribute. If you have encountered the same problem I can recommend you to read section 13.3.7.1 from EJB 3.1 specfication (you can download it here).
Upvotes: 1