3 Replies Latest reply on Mar 21, 2005 2:14 PM by Adrian Brock

    keep getting tx marked for rollback error

    Emily Newbie

      I am using jboss4.0.1 with hibernate, and I created my own HibernateUtil class to manage the sessions and transactions (outside any EJBs). I've posted the code below. However sometimes when committing a random transaction I get this:

      Caused by: javax.transaction.RollbackException: Already marked for rollback TransactionImpl:XidImpl[FormatId=257, GlobalId=***.com/26137, BranchQual=, localId=26137]
      at org.jboss.tm.TransactionImpl.beforePrepare(TransactionImpl.java:1068)
      at org.jboss.tm.TransactionImpl.commit(TransactionImpl.java:296)
      at org.jboss.tm.TxManager.commit(TxManager.java:200)
      at org.jboss.tm.usertx.client.ServerVMClientUserTransaction.commit(ServerVMClientUserTransaction.java:126)
      at com.scilearn.dao.HibernateUtil.commitTransaction(HibernateUtil.java:135)


      I'm not sure why a transaction would be marked for rollback, because I never mark a transaction for rollback in my code, i only commit or rollback right away. I don't see any errors in my logs, however I do see some explicit calls to HibernateUtil.rollbackTransaction. Shouldn't these calls end the transaction? Are there any ideas as to why these transactions marked for rollback may be hanging around?

      
      public class HibernateUtil {
      
       private static org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(HibernateUtil.class);
      
       /**
       * First, start a transaction so that HibernateContext can join the Hibernate session to it
       * @return
       * @throws InfrastructureException
       */
       public static net.sf.hibernate.Session getSession() throws InfrastructureException{
      
       try{
       UserTransaction tm = getTransactionManager();
       if(tm.getStatus() == Status.STATUS_NO_TRANSACTION)
       {
       tm.begin();
       //log.info("started tx " + tm.toString());
       }
      
       Session session = HibernateContext.getSession("java:/HibernateFactory");
      
       return session;
      
       }catch(Exception e)
       {
       throw new InfrastructureException(e);
       }
       }
      
      
       /**
       * The session is tied to the transaction (HibernateContext did this for us),
       * so ending the transaction will return the session and connection to the pool.
       * If the transaction has been left active, roll it back
       */
       public static void closeSession() {
      
       try {
       UserTransaction tx = getTransactionManager();
      
       if(tx.getStatus() == Status.STATUS_ACTIVE || tx.getStatus() == Status.STATUS_MARKED_ROLLBACK)
       {
       log.debug("session to close has an active transaction, will rollback");
       rollbackTransaction();
       }
      
       } catch (Exception e) {
       log.error("Error closing session: " + e);
       } finally {
      
       }
       }
      
      
       /**
       * Leave this blank for now since we do it automatically when we get a session
       * @throws com.scilearn.dao.InfrastructureException
       */
       public static void beginTransaction() throws com.scilearn.dao.InfrastructureException {
       }
      
       public static void commitTransaction() throws com.scilearn.dao.InfrastructureException {
       log.debug("COMMITTING HIBERNATE TRANSACTION");
       try {
       UserTransaction tx = getTransactionManager();
       if(! (tx.getStatus() == Status.STATUS_NO_TRANSACTION))
       tx.commit();
      
       } catch (Exception e) {
       log.error("Error committing transaction: " + e);
       rollbackTransaction();
       throw new InfrastructureException(e);
       }
      
       }
      
       public static void rollbackTransaction() {
       log.info("ROLLING BACK HIBERNATE TRANSACTION");
       try {
       UserTransaction tx = getTransactionManager();
      
       if (tx != null && ! (tx.getStatus() == Status.STATUS_NO_TRANSACTION)) {
       tx.rollback();
       }
      
       } catch (Exception e) {
       log.error("Error rolling back transaction: " + e);
       } finally {
      
       }
       }
      
       public static void flushSession() throws InfrastructureException
       {
       try
       {
       getSession().flush();
       }catch(HibernateException e)
       {
       throw new InfrastructureException(e);
       }
       }
      
       private static UserTransaction getTransactionManager() throws InfrastructureException
       {
       try{
       InitialContext context = new InitialContext();
       UserTransaction tm = (UserTransaction) context.lookup("UserTransaction");
       return tm;
       }catch(Exception e)
       {
       throw new InfrastructureException(e);
       }
      
       }
      
      


        • 1. Re: keep getting tx marked for rollback error
          Adrian Brock Master

          I can see a number of problems with your code
          1) If by outside an EJB you mean a servlet you should use java:comp/UserTransaction
          (although in JBoss there is no difference it optimizes away the client transaction to the server user transaction)
          2) Some of the status checking is wrong
          3) The commit/rollback logic is wrong

          I could help you fix it, but then I don't feel the need since we already provide
          this feature, it is called CMT and it works.
          If you don't want to use tried and tested code, you'll have to debug it yourself.

          On your main question, I have no idea.
          You don't post any useful information -- "READ THIS FIRST".
          My *guess* would be a transaction timeout.

          • 2. Re: keep getting tx marked for rollback error
            Emily Newbie

            I think you are right that it is due to tx timeouts. And it looks like transactions time out when I startup JBoss with a lot of JMS messages in the queue (using oracle for jms persistence). Is there any way I can avoid having these transactions timeout?

            • 3. Re: keep getting tx marked for rollback error
              Adrian Brock Master

               

              "berkgypsy" wrote:
              Is there any way I can avoid having these transactions timeout?

              Yes, figure out what is taking so long or not responding.