3 Replies Latest reply on May 13, 2014 2:47 AM by Puneet Srivastava

    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) annotated method does not run in a separate transaction

    Jan van de klok Newbie

      We run an application with container managed transaction handling.

       

      We have implemented a modeshape persistent storage.

      When a request comes from the browser, a manager class (annotated with @Stateless) handles the request by means of method 'X' . In this manager a transaction is started (which is OK) whne method 'X' is invoked but at some point in the underlying code we call a method that is annotated with

         @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW). This method generates a new id number wich should be stored in the modeshape database. This method is synchronized to avoid generating duplicate numbers.

       

      We would excpect that the @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) causes the container to open a new transaction, generates the new id, and commit that new number to the database.

      Unfortunaltly this does not seem the case, the new generated number not committed (and therefore visible to other sessions) when the @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) annotated method ends.

      It is stored, and visible to other sessions only when method 'X'  ends (which is far too late) and this causes duplicate id's.

       

      We are using JBOSS EAP6.1 with the modeshape module and infinispan as cache. The modeshape usese a postgres database for persisting data.

       

      Can anyone point out what we are missing here??

       

      any help is appreciated

       

      Regards.

       

      Jan van de Klok 

        • 2. Re: @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) annotated method does not run in a separate transaction
          Jan van de klok Newbie

          jaikiran pai, thanks for your response. I looked into the link you send me.

           

          this is our interaction class:

           

          @Stateless

          public class CaseManager

          {

            @Inject

            @DAOType(Type.JCR)

            private CaseDAOInf caseDAO = null;

           

          .....

          ...

          private void createCase(CaseResourcePath parentPath, Case caseObj)

            {

              Preconditions.checkNotNull(caseObj, "No caseObj was supplied");

              Preconditions.checkNotNull(parentPath, "No case resource path was supplied to store the caseObj");

              // Generate unique casenumber

            

              caseObj.setCaseNumber(caseDAO.generateCaseNumber(parentPath));

           

             // first get the case definition that the provided caseObj references

              CaseDefinition caseDef = caseDefMngr.getPublishedCaseDefinitionByPath(caseObj.getCaseDefinitionPath());

              caseObj.setCaseDefinition(caseDef);

           

          ...

          ...

          }

          ---------------------------------------------------------------------

          and this is the CaseDao implementation

           

          @DAOType(Type.JCR)

          @RequestScoped

          public class CaseDAO extends AbstractDAO implements CaseDAOInf

          {

           

          ...

          ...

            @Override

            @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)

            public synchronized long generateCaseNumber(final CaseResourcePath parentPath)

            {

             //   // we expect a new transaction  here

              long number = 100000000;

           

           

              try

              {

                session.refresh(true);

                Node parentNode = session.getNode(parentPath.absolutePath);

           

           

                if (parentNode.hasProperty(PROP_KEY_LAST_ISSUED_ID))

                {

                  javax.jcr.Property lastIssuedId = parentNode.getProperty(PROP_KEY_LAST_ISSUED_ID);

                  number = lastIssuedId.getLong() + 1;

                }

           

           

                parentNode.setProperty(PROP_KEY_LAST_ISSUED_ID, number);

                session.save();

                return number;    // we expect the transaction to commit here

              }.

          catch (RepositoryException e)

              {

                logger.error("Could not issue a new casenumber on path  {}", parentPath.absolutePath);

                throw Throwables.propagate(e);

              }

            }

           

          ...

          ...

          }

          -----------------------------------------

          So why is this not working? It is calling the method on the business object of the bean  or not??