Вопрос

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:

  1. Message driven bean onMessage(Message) was called.
  2. Message driven bean perform some actions successful and then invoke B.process(Message) method.
  3. Something bad in B occurred and RuntimeException was thrown.
  4. RuntimeException was wrapped in EJBException and was successfully catched by message driven bean.
  5. Message driven bean onMessage(Message) method was executed completely, but its transaction was marked for rollback.

Can anybody explain this behaviour? Thanks in advance.

Это было полезно?

Решение 2

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).

Другие советы

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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top