2

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.

Richard Sitze
  • 8,262
  • 3
  • 36
  • 48
gkuzmin
  • 2,414
  • 17
  • 24
  • What appserver/version are you using? This links suggests your assessment is correct, in that your code should work: http://stackoverflow.com/questions/10817838/ejb-3-0-nested-transaction-requires-new. – Richard Sitze Jul 31 '12 at 21:34
  • You might also try to put together a *minimal* example of the two beans - first to verify that you do or don't see expected behavior with all your other "stuff" removed, and second to give others something to play with on another platform. No promises here though. – Richard Sitze Jul 31 '12 at 21:55
  • I use WebLogic 12c server. Currently I can not provide any example which can be assembled and deployed, but I will try to provide it in next 10-20 hours. Maybe I will find problem while trying to provide an example. :) – gkuzmin Jul 31 '12 at 21:59
  • 1
    I took the liberty of dropping the EJB3 tag and adding weblogic; that may be more relevant here than the other. You'll not offend me if you change it back. – Richard Sitze Jul 31 '12 at 23:41
  • This is a relevant tag, so why not? – gkuzmin Aug 01 '12 at 06:33
  • 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. Realy dump situation, btw. Now I am wondering how to close this question because of its useless. – gkuzmin Aug 01 '12 at 09:53
  • 1
    It's not really useless; add your own answer & accept it. It could be very helpful to someone else. – Richard Sitze Aug 01 '12 at 14:03
  • The code in the question does not represent the actual code as described in the answer: "actually TransactionAttribute annotation was placed on abstract superclass of B" and so the question/answer is misleading. – mic.sca Dec 18 '17 at 10:41

2 Answers2

2

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.

alexsmail
  • 5,661
  • 7
  • 37
  • 57
1

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

gkuzmin
  • 2,414
  • 17
  • 24