1 Reply Latest reply on Feb 18, 2010 4:52 PM by Nicolas Bielza

    TransactionInterceptor leaks transactions

    Nicolas Bielza Newbie

      Hello,


      I have a custom servlet running behind Seam ContextFilter so it can participate in Seam requests (not JSF requests). The servlet calls a @Transactionnal JavaBean which throws an application exception.
      The exception then propagates back to the servlet. My problem is that the transaction that was started when entering the transactionnal JavaBean does not end, leaving locks in the database.


      The problem seems to be in org.jboss.seam.util.Work.workInTransaction():




            try
            {
               if (newTransactionRequired) 
               {
                  log.debug("beginning transaction");
                  userTransaction.begin();
               }
      
               T result = work();
               if (newTransactionRequired) 
               {
                  if (transaction.isMarkedRollback())
                  {
                     log.debug("rolling back transaction");
                     userTransaction.rollback(); 
                  }
                  else
                  {
                     log.debug("committing transaction");
                     userTransaction.commit();
                  }
               }
               return result;
            }
            catch (Exception e)
            {
               if (newTransactionRequired && userTransaction.getStatus() != Status.STATUS_NO_TRANSACTION && isRollbackRequired(e, true)) 
               {
                  log.debug("rolling back transaction");
                  userTransaction.rollback();
               }
               throw e;
            }
      



      The catch clause does not handle the case when the transaction was started by the interceptor and needs to be commited. I cloned this class, changing the catch clause like this and it fixed the transaction leak problem:




            catch (Exception e)
            {
               if (newTransactionRequired && userTransaction.getStatus() != Status.STATUS_NO_TRANSACTION) {
                    if(isRollbackRequired(e, true)) {
                       log.debug("rolling back transaction");
                       userTransaction.rollback();
                    } else {
                          log.debug("committing transaction");
                          userTransaction.commit();
                    }
               }
               throw e;
            }
      



      Should I report this as a bug in Jira ?


      Thanks for your time,


      Nicolas