5 Replies Latest reply on Jun 4, 2013 11:25 AM by bvg

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

      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

        • 1. Re: Performance costs of having a transaction over multiple EJBs vs. one EJB
          jaikiran

          Bernhard Gunten wrote:

           

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

          1) Who calls this outer EJB and how?

          2) Does the caller have any tx context associated when the outer EJB is called?

          3) How many times is it called?

          4) How is the "terminal" variable in that code set?

          5) How are you measuring those numbers?

          • 2. Re: Performance costs of having a transaction over multiple EJBs vs. one EJB

            Hello and thanks for your reply

             

            1) Who calls this outer EJB and how?

             

            It's a "EJB Client" in another JVM. It just uses the remote interface. The client is the same client for the scenario A or scenario B (of course with different interfaces).

             

            2) Does the caller have any tx context associated when the outer EJB is called?

             

            No, the client does not hav any tx context. That's why we also "moved" the REQUIRES_NEW for scenario B to the outer EJB as it was first in the inner EJB.

             

            3) How many times is it called?

             

            We called the both components for multiple 10k times. All the requests are sent sequential, so no parallel requests are in the system.

             

            4) How is the "terminal" variable in that code set?

             

            It's a local interface which we lookup through JNDI. The terminal is set in the @PostConstruct of the EJB.

             

            Remark: First the inner EJB doing the persist call was a remote interface in a different EAR on the same JBoss instance (there were reasons). After seeing the huge time "loss" we moved it into the same EAR and declared the interface as @Local to eliminate this concern. Though, the lookup by JNDI is still there, and we might/should try to get the terminal by @EJB annotation!?

             

            5) How are you measuring those numbers?

             

            Mainly, the client sending the requests is printing out the calls per second. Of course this varies a bit: 4.5 - 5.5 sec on direct calls on the terminal EJB,  and 25-27 sec by calling the "dispatcher" EJB for each 5000 calls.  The amount of used transactions we get from the JPA panel in the admin GUI.

             

            Thanks for your help, and greetings from Switzerland

             

            Bernhard

            • 3. Re: Performance costs of having a transaction over multiple EJBs vs. one EJB
              wdfink

              What if you use injection for the 'terminal' variable with @EJB instead of set in @PostConstruct?

              Also would be interesting if you remove the DB access, this is to check where the time is spend.

              How do you get the EntityManager reference?

               

              You can add an interceptor (or even add logging) to show how long the methods need.

              Maybe you can attach a simple example.

              • 4. Re: Performance costs of having a transaction over multiple EJBs vs. one EJB
                jaikiran

                To be honest, I don't see why there would be such a big difference in numbers when you change the approach. Technically, it ultimately is effectively the same 1 tx per record insertion. If you have a reproducible application (both client side and server side), please attach it to this thread.

                • 5. Re: Performance costs of having a transaction over multiple EJBs vs. one EJB

                  Hello

                   

                  thanks for your further replies. I will of course happily create an exmple of client and EJBs. Meanwhile I've tried to profile the application a bit, to see the main differences between going trough one or both EJBs.

                   

                  Looking at the VisualVM Output going trough both EJBs i saw a lot of time spent in arjuna operations (closeAndUnlock, writeState, removeState etc), which does not happen in the same way calling the second (writing) EJB directly:

                   

                  visvm.png

                  I'm running this all on a Windows PC and on further tries I saw some file operations in this directory during the measurements:

                   

                  ..\standalone\data\tx-object-store\ShadowNoFileLockStore\defaultStore\StateManager\BasicAction\TwoPhaseCoordinator\AtomicAction

                   

                  So perhaps I just try to solve a poor "host-system" problem?! Or did I just configure the DS / objectstore wrongly?!

                   

                  Thanks for any help guys!

                   

                  Bernhard