0 Replies Latest reply on Mar 23, 2010 6:33 PM by totto

    Avoiding IllegalStateException ("transaction not active") in org.jboss.seam.transaction.EntityTransaction

      I would like to suggest the following change to EntityTransaction.java (in org.jboss.seam.transaction). Reasons are explained at the end of this message.



         public int getStatus() throws SystemException
         {
            // $TO 20100318 Patch: getRollbackOnly() throws IllegalStateException, if getActive() = false !        
            if ( isEntityManagerSet() && getDelegate(). isActive() && getDelegate().getRollbackOnly() )
            {
               return Status.STATUS_MARKED_ROLLBACK;
            }
            else if ( isEntityManagerSet() && getDelegate().isActive() )
            {
               return Status.STATUS_ACTIVE;
            }
            else
            {
               return Status.STATUS_NO_TRANSACTION;
            }
         }
      



      What did I change?


      In the line: if ( isEntityManagerSet() && getDelegate(). isActive() && getDelegate().getRollbackOnly() )


      I inserted getDelegate(). isActive() BEFORE getDelegate(). getRollbackOnly() becuase getRollbackOnly() throws an IllegalStateException (transaction not active) if the transaction isn't active. I believe the method getStatus() should return "STATUS_NO_TRANSACTION" if thats what the delegate says (it does, when the transaction is not active)! It shouldn't throw the IllegalStateException.


      I have come across that problem, when running a Seam 2.1.2 application inside a IBM WebSphere 6.1.0.17 container (no EJB3 feature pack) letting seam handle the transactions (-> so Bean-Managed-Transaction (BMT) from the viewpoint of the container). The problem first occurs when a transaction of a timer or web services interface goes into timeout (transaction timeout). After that timeout the one thread that the transaction timeout occured in, can't use seam managed transactions any more. And that's because inside the woven-in code for transaction management getStatus() is called. And that leads to an IllegalStateException (transaction not active) when any transactional method of that timer thread is called. It might be that I am doing something wrong initializing the seam lifecycle on the timer thread (it's obviously not a http thread that is handled by seam by default!). And I am observing, that the problem is bound to the thread the transaction timeout occured in.


      So there might be something else wrong, because transaction handling works fine, until the first transaction timeout occurs on a timer thread (no problem on a gui / web thread !)


      But please comment on my suggestion to change EntityTransaction.java from seam version 2.1.2. I belive the contract for getStatus() should be to not throw an IllegalStateException when a transaction is not active but to return "STATUS_NO_TRANSACTION" in that case.


      Thanks for your comments!
      Tobias.