REQUIRES_NEW within REQUIRES_NEW within REQUIRES_NEW ... on and on
Asked Answered
F

2

4

JBoss 4.x
EJB 3.0

I've seen code like the following (greatly abbreviated):

@Stateless
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public class EJB1 implements IEJB1
{
   @EJB
   private IEJB1 self;

   @EJB 
   private IEJB2 ejb2;

   @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
   public boolean someMethod1()
   {
     return someMethod2();
   }

   @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
   public boolean someMethod2()
   {
     return self.someMethod3();
   }

   @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
   public boolean someMethod3()
   {
     return ejb2.someMethod1();
   }
}

And say EJB2 is almost an exact copy of EJB1 (same three methods), and EJB2.someMethod3() calls into EJB3.someMethod1(), which then finally in EJB3.someMethod3() writes to the DB.

This is a contrived example, but have seen similar code to the above in our codebase. The code actually works just fine.

However, it feels like terrible practice and I'm concerned about the @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) on every method that doesn't even actually perform any DB writes. Does this actually create a new transaction every single time for every method call with the result of:

new transaction
-new transaction
--new transaction
---new transaction
...(many more)
-------new transaciton (DB write)

And then unwraps at that point? Would this ever be a cause for performance concern? Additional thoughts?

Fructify answered 8/12, 2011 at 17:49 Comment(0)
Z
12

Does this actually create a new transaction every single time for every method call

No, it doesn't. The new transaction will be created only when calling method by EJB reference from another bean. Invoking method2 from method1 within the same bean won't spawn the new transaction.

See also here and here. The latter is exceptionally good article, explaining transaction management in EJB.

Edit:
Thanks @korifey for pointing out, that method2 actually calls method3 on bean reference, thus resulting in a new transaction.

Zymase answered 8/12, 2011 at 18:2 Comment(3)
He injects the second bean via @EJB, not just calling method. self.someMethod3() - STARTS TRANSACTIONGooseneck
Thank you for your answer jFrenetic - do you have any insight on performance implications of needlessly invoking new transactions in chained method calls where no DB writes are done (until at the very end as my question explains)? Is it negligible (as in I shouldn't worry about it), or is it significant enough for me to raise a stink over it and then try to cleanup our existing code?Fructify
Well, EJB transactions go far beyound DB writes. I insist you on reading the article I provided in the second link, it'll give you much more insight on how the transactions are handled by container. I'd say it depends, sometimes it's crucial for a method to spawn a new transaction (see the "Dealing with exceptions" section in the mentioned article). Also Sun's official J2EE tutorial recommends on using @REQUIRED (the default) in early phases of development.Zymase
G
4

It really creates new JTA transaction in every EJB and this must do a serious performance effect to read-only methods (which makes only SELECTS, not updates). Use @SUPPORTS for read-only methods

Gooseneck answered 8/12, 2011 at 17:56 Comment(7)
-1 The answer is wrong. No transaction is created in local method calls.Zymase
Alright, taking back my down vote. I was looking at method1 implementation.Zymase
Crap, that's impossible unless you edit your answer. Sorry about that.Zymase
No problem, everybody mistakes 8)Gooseneck
You say that it seriously affects performance of read-only methods on the DB. Why is that? My assumption is that you are needlessly creating transactions for an operation that doesn't require a transaction (IE just the SELECTs). Secondly, creating a new transaction for each chained method call that say 10 calls later finally performs the DB write - is this still not a performance problem? Would this not still result in 10 different transactions that then unwind after the DB write?Fructify
Guess you probably won't be checking back. In any case, thank you for your answer +1.Fructify
@Zymase your first comment saved my dayRenal

© 2022 - 2024 — McMap. All rights reserved.