0 Replies Latest reply on Aug 13, 2007 1:30 PM by John McClain

    3 questions on transactions - misunderstanding or bug

    John McClain Newbie

      I will give the pertinent code for 3 use cases and describe the outcomes. The outcomes dont make sense for my understanding of EJB3.0.
      the function batchRemoveEndedProcesses does a simple delete from an oracle db. All this is in a SLSB



      @TransactionAttribute(javax.ejb.TransactionAttributeType.REQUIRED)
      public void cleanupEndedProcesses(String processId)
      .
      .
      while (pidVec.size() > 1075)
      {
       endNdx = pidVec.size() > BATCHSIZE? BATCHSIZE:pidVec.size();
       tmpList = new ArrayList<String>(pidVec.subList(0, endNdx));
       batchRemoveEndedProcesses(tmpList, jbpmDAO);
       cnt += endNdx;
       pidVec.removeAll(tmpList);
      }
      .
      .
      @TransactionAttribute(javax.ejb.TransactionAttributeType.REQUIRES_NEW)
      private void batchRemoveEndedProcesses(List<String> pidVec, JbpmDAO jbpmDAO)
      {
       try {
       jbpmDAO.removeEndedProcesses(pidVec);
       }
       catch (Exception e) {
       throw new WorkflowException(e);
       }
      }
      
      

      first call to removeEndedProcesses succeeds, second call succeeds
      start: 1080 rows to be deleted
      end1 removeEndedProcesses : 1080 rows to be deleted
      end2 removeEndedProcesses : 1080 rows to be deleted
      end: 1070 - 10 rows deleted
      ISSUE: WHY DOES THE REQUIRES_NEW FUNCTION NOT COMMIT
      i UNDERSTOOD THAT WHEN YOU HAVE REUQIRES_NEW, THE FUNCTION WILL COMMIT ITS TRANSACTION
      --------------------------------------------------------------------------------

      @TransactionAttribute(javax.ejb.TransactionAttributeType.NEVER)
      public void cleanupEndedProcesses(String processId)
      .
      .
      while (pidVec.size() > 1075)
      {
       endNdx = pidVec.size() > BATCHSIZE? BATCHSIZE:pidVec.size();
       tmpList = new ArrayList<String>(pidVec.subList(0, endNdx));
       batchRemoveEndedProcesses(tmpList, jbpmDAO);
       cnt += endNdx;
       pidVec.removeAll(tmpList);
      }
      .
      .
      @TransactionAttribute(javax.ejb.TransactionAttributeType.REQUIRES_NEW)
      private void batchRemoveEndedProcesses(List<String> pidVec, JbpmDAO jbpmDAO)
      {
       try {
       jbpmDAO.removeEndedProcesses(pidVec);
       context.setRollbackOnly();
       }
       catch (Exception e) {
       throw new WorkflowException(e);
       }
      }
      
      

      first call to removeEndedProcesses succeeds. Whenrollback called and throws exception
      Caused by: java.lang.IllegalStateException: setRollbackOnly() not allowed without a transaction.
      start: 1080
      end1 removeEndedProcesses : 1080
      end: 1080
      ISSUE: Why does CODE act as if REQUIRES_NEW is not there?
      --------------------------------------------------------------------------------
      @TransactionAttribute(javax.ejb.TransactionAttributeType.REQUIRED)
      public void cleanupEndedProcesses(String processId)
      .
      .
      while (pidVec.size() > 1075)
      {
       endNdx = pidVec.size() > BATCHSIZE? BATCHSIZE:pidVec.size();
       tmpList = new ArrayList<String>(pidVec.subList(0, endNdx));
       batchRemoveEndedProcesses(tmpList, jbpmDAO);
       cnt += endNdx;
       pidVec.removeAll(tmpList);
      }
      .
      .
      @TransactionAttribute(javax.ejb.TransactionAttributeType.REQUIRES_NEW)
      private void batchRemoveEndedProcesses(List<String> pidVec, JbpmDAO jbpmDAO)
      {
       try {
       jbpmDAO.removeEndedProcesses(pidVec);
       context.setRollbackOnly();
       }
       catch (Exception e) {
       throw new WorkflowException(e);
       }
      }
      

      first call removeEndedProcesses succeeds (no commit) and then does rollback with no exception. Second call removeEndedProcesses throws esception when getting a connection:
      Caused by: javax.resource.ResourceException: Transaction is not active: tx=TransactionImpl:XidImpl[FormatId=257, GlobalId=ro-0029aits/47, BranchQual=, localId=47]
      ISSUE: Why does rollback screw things up for the next run through the REQUIRES_NEW function?
      ---------------------------------------------------------------------------

      The only way I could get above deletes to commit as I wanted (in batches) was if the loop above was in a javax.ejb.TransactionAttributeType.NEVER function; This should not be necessary(I thought).
      In addition, for unit testing, I wanted to rollback via context.setRollbackOnly(), and I could not get that to work ;