Performance costs of having a transaction over multiple EJBs vs. one EJB
Asked Answered
B

1

9

I have a question about transaction performance and/or costs in following scenarios.

Environment: JBoss 7.1.1 / Oracle 11G / Java 6

Scenario A - 1 EJB:

I've created one EJB which saves a record to a database with CMP (Transaction REQUIRES_NEW):

@Override
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)  
public void saveTerminal(TerminalSaveRequest request) {
    TerminalEntity terminalEntity = new TerminalEntity();
    terminalEntity.setId(request.getId());
    ...

    entityManager.persist(terminalEntity);
}

This EJB is called by an external EJB Client (without any JTA trx) and performes well (1000 inserts / sec). JBoss also documents the exact amount of transactions in the JPA measurement.

Scenario B - 2 EJBS:

I've changed the application and added a further EJB calling the EJB from scenario A, though here I would like to have a "shared" transaction opened by the new EJB. So I've changed the existing EJB as followed (Transaction REQUIRED):

@Override
@TransactionAttribute(TransactionAttributeType.REQUIRED)  
public void saveTerminal(TerminalSaveRequest request) {
    TerminalEntity terminalEntity = new TerminalEntity();
    terminalEntity.setId(request.getId());
    ...

    entityManager.persist(terminalEntity);
}

In the new EJB I start then the newly required transaction and calling the (local) EJB:

@Override
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)  
public void saveTerminal(TerminalSaveRequest request) {
    terminal.saveTerminal(request);
}

Now, again everything works as expected (same amount of transactions etc), though the performance has dropped dramatically from 1000 to 200 inserts a second which bothers a lot as the transaction handling between these two EJBs seems to cost like 4 times the insert :(

Further informations:

  • No other EJBs or methods are using this transaction.
  • Local interfaces
  • Local DS

Questions:

  • Is it really THAT expensive to have a transaction opened in one EJB and used in another? (As there is still one transaction and one insert as in the first example).
  • If one has one "Dispatcher" calling multiple other EJBs in one transaction will the cost of transaction handling be once per transaction or once per EJB call?!

If more informations are needed I'll happily post more.

Thanks for any hints or thoughts about this topic.

Bernhard

Bashemeth answered 30/5, 2013 at 8:33 Comment(4)
I don't know what's wrong, but I'm doubtful that adding a no-op REQUIRED would cause a problem. Is there an interceptor assigned to the EJBs? Is there a security difference (e.g., @RunAs)? Can you run a profiler against both versions to see where the time is going?Elutriate
No, there is no such thing going on. I've even introduced an echo service, on both EJBs just without the PERSIST and then the response times are pretty similar, with one EJB or both chained together (+/- 10% overhead for going trough both EJBs).Bashemeth
There will inevitably be some overhead from going through an extra proxy. How much real time is 10%? I still recommend a profiler, but I otherwise have no other suggestions, sorry.Elutriate
I'll check with the profiler of course, sorry didn't mention it already ... will get back to that & you ;-) Thanks anyways for your help!Bashemeth
P
3

Have you tried having both EJB's use @TransactionAttribute(TransactionAttributeType.REQUIRED) and letting JBoss decide where to demarcate the transaction instead?

Plectognath answered 1/6, 2013 at 22:53 Comment(2)
Yes I did, having REQUIRED in the inner and outer EJB does not have an impact on the global "result". But that's just for understanding the problem, in rl I need a shared transaction going in to the second EJB.Bashemeth
If I understand your description correctly, there was no JTA transaction with one EJB, correct? My guess is this has something to do with JTA entering the picture. When you had only one EJB, you didn't need JTA and the container didn't use it, because you weren't dealing with more than one transactional resource. Now, you have two EJB's, and the transaction must not only span the DB insert, but the EJB call as well. Can you set the JTA log level to DEBUG and see if JTA transactions are in fact being used?Plectognath

© 2022 - 2024 — McMap. All rights reserved.