1 Reply Latest reply on Jan 23, 2008 12:19 PM by pmuir

    Transaction demarcation problem

      i need to update thousands of independent records in sheduled environment.

      For efficiency reasons I need to do that in a big loop ( set of loops)
      also because the underlying info is externaly organised like that.

      I disabled the seam control over transactions
      I'm trying to disable container management over transactions

      but so far I realy can not Use transaction control in the environment
      there is always something wrong !!
      If not seen any effect of a flush and I'm losing all the work done
      due to the fact I need to rollback a single item transaction

      process

      
       Connect external
       loop
       update record
       if (fails)
       Rollback this ONLY RECORD WITHOUT ANY IMPACT
       ON THE REST OF THE ENVIRONMENT
       handle next
      




      It is very important the overall process is not aborted on any individual error.
      (this is what is happening in the actual case with a fail rate on 1 on 1000 this means
      I never get never nothingthing done !!!!)

      at this time I use following code to handle the transaction

      as I'm working in a seam environment
      I switched to manual transaction handling
      and I'm bouncing/fighting against JTA CONTAINER - BEAN managed transactions

      code :

      
      @Name("loopscan")
      @TransactionManagement(TransactionManagementType.BEAN) //kill container management
      @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) //suspend all active container transactions
      public class BatchTransactions
      {
      // @Logger
       private Log log;
      // @In ("#{entityManager}")
       public EntityManager em;//allow for db ACCESS
       Session ses=null;//session indicator
       String env="Init";
       // org.hibernate.Transaction txn=null;//hibernate transaction
      public BatchTransactions() {}
      public void initTransaction()
      {
      }
      public Exception sequence()
      {
       Exception errcod=null;
       org.hibernate.Transaction txn=null;//
       boolean rollback=false;
       //reset timeout
       try { env="Timeout";
       org.jboss.seam.transaction.Transaction.instance().setTransactionTimeout(60*60*10000000);
       } catch (Exception er)
       {errcod=er;
       String errmsg=er.getClass().getSimpleName() +" err: "+ er.getMessage();
       log.error(env+" Modifying timeout failed "+ errmsg);
       }
       // seam timeout
       try { env ="seam timeout";
       Transaction.instance().setTransactionTimeout(60*60*10000000);} catch (Exception er)
       {errcod=er;
       String errmsg=er.getClass().getSimpleName() +" err: "+ er.getMessage();
       log.error(env+" Modifying Seam timeout failed "+ errmsg);
       }
       //
       //connect to session
       //
       env="setup";
       ses=(Session) em.getDelegate();//get the session
      
       //
       // transaction with own error handling
       //
       try { env="Begin";// Begin the transaction ?
       txn=ses.getTransaction();
       if(!txn.isActive())
       txn.begin();// txn=ses.beginTransaction(); **********************
       // txn.setTimeout(500000);
       } catch (Exception er )
       {errcod=er;
       String errmsg=er.getClass().getSimpleName() +" err: "+ er.getMessage();
       log.error(env+" starting transaction failed "+ errmsg);
       }
       try {env="execute "; //ececution process
       errcod=Execute();//do the DB operations
       try {//flush the info to other users
       ses.flush();
       } catch (Exception er )
       {errcod=er;rollback=true;
       String errmsg=er.getClass().getSimpleName() +" err: "+ er.getMessage();
       log.error("Flush "+env+" Commiting transaction failed "+ errmsg);
       }
      
       try {//commit the information
       txn.commit();
       } catch (Exception er )
       {errcod=er;rollback=true;
       String errmsg=er.getClass().getSimpleName() +" err: "+ er.getMessage();
       if (errmsg.indexOf("NullPointerException")>-1)
       log.error("Commit "+env+" Commit nullpointer exception failed "+ errmsg,er);
       else log.error(env+" Commiting transaction failed "+ errmsg);
       }
      
       } catch( GenericJDBCException er)
       {String errmsg=er.getClass().getSimpleName() +" err: "+ er.getMessage();rollback=true;
       // if (errmsg.indexOf("Cannot open connection")>-1)
       // { if (!em.isOpen()) log.info("Em session still open !");
       // try {if (ses==null) {ses=(Session) em.getDelegate();}//get the session
       // txn=ses.beginTransaction();
       log.error(env+" Cannot open connection "+ errmsg,er);
       }
       catch (Exception er) {FatalStatus();errcod=er;rollback=true;
       String errmsg=er.getClass().getSimpleName() +" err: "+ er.getMessage();
       if (errmsg.indexOf("NullPointerException")>-1)
       log.error(env+" nullpointer exception failed "+ errmsg,er);
       else log.error(env+" overall transaction error "+ errmsg);
       }
       if (rollback)
       try {//rollback cover
       txn.rollback();
       } catch (Exception er)
       {errcod=er;
       String errmsg=er.getClass().getSimpleName() +" err: "+ er.getMessage();
       log.error("Rollback "+env+" Rollback transaction failed "+ errmsg +" From "+ errmsg);
       }
       //
       // detect losing the session
       //
       if (ses==null)
       { if (!(em.isOpen())) log.info("em session closed !");
       }
       return errcod;
      
      }
      /*
      */
      public void TxnSts(String env) {this.env=env;}
      public Exception Execute() throws Exception {return null;};
      public void FatalStatus() {};
      }
      {
      

      As you can see most of the code is error trapping and reporting

      It fails at the BEGIN transaction
      stating : TransactionException err: Could not register synchronization for container transaction

      The default for the bean is set to BEAN transactions
      but still it considers it a Container transaction


      any suggestions would be more then welcome