2 Replies Latest reply on Jul 7, 2004 9:31 PM by gareth_mahon

    Marking transactional boundaries

    gareth_mahon

      Hi All,

      The problem context:

      I have a collection of session bean facades that manage a set of entity beans. All beans are configured with a transactional attribute of 'Required'. The container configuration is set to commit option A.

      The problem:

      I still get a plethora of ejbLoad() and ejbStore() callbacks on beans that should be cached in memory. This implies to me that a transactional boundary is being crossed - but I don't know where.

      Does anyone have any clues for me to chase down?

      Thanks for your time in advance,

      Gareth

        • 1. Re: Marking transactional boundaries
          jamesstrachan

          Gareth,

          The EJB Specification mandates that (a) ejbLoad() must be called before a business method in a transaction is executed, and that (b) ejbStore() must be called after a business method is executed.

          a) is designed to prevent a business method in a transaction being executed on data that is out of synch. with the underlying database.

          b) is designed to ensure that changed data is always written back to the underlying database. The container cannot "know" whether the method call changed data, so the safe option is to always write.

          You can reduce the number of ejbLoad() calls by changing the transactional attribute for read methods to 'Supports'. This applies both to the Entity Beans and to read methods on the Session Beans.

          You can't reduce the number of ejbStore() calls, but you can reduce their effect. If you are using CMP, the CMP layer should work out that nothing has changed and do no work.

          If you are using BMP, you can use a dirty flag to identify when data has changed - and avoid the update if nothing has changed. See example below :-

           boolean dirty;
          
           public void ejbLoad() {
          
           // Load data
          
           dirty = false;
           }
          
           public void changeData( ... ) {
          
           // Change data
           dirty = true;
           }
          
           public void ejbStore() {
          
           logger.info( "In ejbStore " + dirty );
           if ( dirty ) {
           doRealStore();
           dirty = false;
           }
          
           }
          
           private void doRealStore() {
          
           // Update data.
          
           }
          


          I posted a complete entity bean on this forum about two weeks ago that uses this technique.

          James


          • 2. Re: Marking transactional boundaries
            gareth_mahon

            James,

            Thanks for you tips.

            I managed to fix the problem in the following way:

            1. My Jboss configuration file was wrong. Commit option A was not being used, commit option B was - I was using an old DTD.

            2. I used the tag <sync-on-commit-only>true</sync-on-commit-only> in the JBoss file.

            Thanks for your time,

            Gareth