1 Reply Latest reply on Dec 1, 2009 7:15 AM by pbrewer_uk

    UserTransaction.rollback still associated with current threa

    pbrewer_uk

      I'm using JBoss AS 5.1.0.GA (with Seam 2.2.0.GA) and have a SLSB with Bean Managed Transactions and I cannot start a new tx after a rollback.

      When I call userTransaction.rollback() and then later want to call userTansaction.begin() - but after the call to rollback, I would expect the tx status to be 6 (i.e. no tx) however the tx status is actually 1 (i.e. javax.transaction.Status.STATUS_MARKED_ROLLBACK). So, this means I cannot start a new tx after rolling back the previous transaction.

      According to the UserTansaction API, calling rollback should:
      "Roll back the transaction associated with the current thread. When this method completes, the thread is no longer associated with a transaction."

      I also noticed https://jira.jboss.org/jira/browse/JBAS-6116, which is closed, but seems to match what is happening.

      Am I doing something wrong? I've included some code extracts below...

      Any help on this would be greatly appreciated,
      thanks, Pete.

      ArchiveBean.java

      @Stateless
      @TransactionManagement(TransactionManagementType.BEAN)
      @Name("archive")
      public class ArchiveBean extends TransactionalSessionBean implements Archive {
      
       public void archiveData() {
       try {
       beginTransaction(300);
       boolean error = true ; // would normally doSomeWork() here.
       if (error) {
       rollbackTransaction() ;
       } else {
       commitTransaction() ;
       }
      
       beginTransaction() ; // Error occurs here as tx Status is 1
      
       ...
      
      
       } finally {
       cleanupTransaction() ;
       }
       }
      }
      



      TransactionalSessionBean.java
      public class TransactionalSessionBean extends Controller {
       @Resource
       private UserTransaction userTransaction;
      
       protected void beginTransaction(int timeout) throws TransactionException {
       Integer txStatus = null;
       try {
       txStatus = userTransaction.getStatus();
       userTransaction.setTransactionTimeout(timeout);
       userTransaction.begin();
       } catch (SystemException ex) {
       throw new TransactionException("Error starting a new transaction.", ex);
       } catch (NotSupportedException ex) {
       throw new TransactionException("A new transaction is not supported.", ex);
       }
       }
      
       protected void rollbackTransaction() throws TransactionException {
       Integer txStatus = null;
       try {
       txStatus = userTransaction.getStatus();
       if (txStatus == Status.STATUS_ACTIVE) {
       userTransaction.rollback();
       } else if (txStatus == Status.STATUS_ROLLING_BACK || txStatus == Status.STATUS_ROLLEDBACK || txStatus == Status.STATUS_MARKED_ROLLBACK) {
       getLog().debug("Not rolling-back tx - it's is already rolled-back, rolling back or marked for rollback. Tx status: " + txStatus);
       } else {
       throw new TransactionException("Cannot rollback a transaction that is not active (tx status " + txStatus + ").");
       }
       } catch (SystemException ex) {
       throw new TransactionException("Error rolling back the current transaction.", ex);
       } catch (SecurityException ex) {
       throw new TransactionException("Rolling back a transaction is not permitted.", ex);
       } catch (IllegalStateException ex) {
       throw new TransactionException("Error rolling back a transaction.", ex);
       }
       }
      
      }
      


        • 1. Re: UserTransaction.rollback still associated with current t
          pbrewer_uk

          I've found the problem - it was with my code. The red highlighted code should move to the blue highlighted code so that a tx marked for rollback gets rolled-back. I hope that is of help to others.

           try {
           txStatus = userTransaction.getStatus();
           if (txStatus == Status.STATUS_ACTIVE || txStatus == Status.STATUS_MARKED_ROLLBACK
           ) {
           userTransaction.rollback();
           } else if (txStatus == Status.STATUS_ROLLING_BACK || txStatus == Status.STATUS_ROLLEDBACK || txStatus == Status.STATUS_MARKED_ROLLBACK
           ) {
           getLog().debug("Not rolling-back tx - it's is already rolled-back, rolling back or marked for rollback. Tx status: " + txStatus);
           } else {
           throw new TransactionException("Cannot rollback a transaction that is not active (tx status " + txStatus + ").");
           }
           } catch (SystemException ex) {
           throw new TransactionException("Error rolling back the current transaction.", ex);
           } catch (SecurityException ex) {
           throw new TransactionException("Rolling back a transaction is not permitted.", ex);
           } catch (IllegalStateException ex) {
           throw new TransactionException("Error rolling back a transaction.", ex);
           }