diff --git a/nuxeo-platform-webapp-core/src/main/java/org/nuxeo/ecm/webapp/shield/SeamExceptionHandlingListener.java b/nuxeo-platform-webapp-core/src/main/java/org/nuxeo/ecm/webapp/shield/SeamExceptionHandlingListener.java
--- a/nuxeo-platform-webapp-core/src/main/java/org/nuxeo/ecm/webapp/shield/SeamExceptionHandlingListener.java
+++ b/nuxeo-platform-webapp-core/src/main/java/org/nuxeo/ecm/webapp/shield/SeamExceptionHandlingListener.java
@@ -20,11 +20,10 @@
 
 import javax.faces.component.UIViewRoot;
 import javax.faces.context.FacesContext;
-import javax.faces.event.PhaseId;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-import javax.transaction.SystemException;
+import javax.transaction.UserTransaction;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -36,9 +35,8 @@
 import org.jboss.seam.mock.MockApplication;
 import org.jboss.seam.mock.MockExternalContext;
 import org.jboss.seam.mock.MockFacesContext;
-import org.jboss.seam.transaction.Transaction;
-import org.jboss.seam.transaction.UserTransaction;
 import org.nuxeo.ecm.platform.web.common.exceptionhandling.service.NullExceptionHandlingListener;
+import org.nuxeo.ecm.platform.web.common.tx.TransactionsHelper;
 
 /**
  * Plays with conversations, trying to rollback transation.
@@ -55,6 +53,8 @@
     public void beforeSetErrorPageAttribute(Throwable t,
             HttpServletRequest request, HttpServletResponse response)
             throws IOException, ServletException {
+        // check seam context
+
         // cut/paste from seam Exception filter.
         // we recreate the seam context to be able to use the messages.
 
@@ -94,14 +94,6 @@
         FacesLifecycle.beginExceptionRecovery(facesContext.getExternalContext());
     }
 
-    @Override
-    public void afterDispatch(Throwable t, HttpServletRequest request,
-            HttpServletResponse response) throws IOException, ServletException {
-        FacesContext context = FacesContext.getCurrentInstance();
-        FacesLifecycle.endRequest(context.getExternalContext());
-        context.release();
-    }
-
     /**
      * Rollbacks transaction if necessary
      */
@@ -109,47 +101,31 @@
     public void startHandling(Throwable t, HttpServletRequest request,
             HttpServletResponse response) throws ServletException {
         try {
-            rollbackTransactionIfNecessary(t, response);
-        } catch (IllegalStateException e) {
-            throw new ServletException(e);
-        } catch (SystemException e) {
-            throw new ServletException(e);
+            UserTransaction ut = TransactionsHelper.getUserTransaction();
+            if (ut != null && TransactionsHelper.isTransactionActive()) {
+                ut.setRollbackOnly();
+            }
+            if (log.isDebugEnabled()) {
+                log.debug("Marking transaction as rollback only");
+            }
+        } catch (Throwable newThrowable) {
+            log.error("Unable to rollback transaction", newThrowable);
         }
     }
 
-    private void rollbackTransactionIfNecessary(Throwable t,
-            HttpServletResponse response) throws ServletException,
-            IllegalStateException, SecurityException, SystemException {
-        if (Contexts.isEventContextActive()) {
-            if (Transaction.instance().isActiveOrMarkedRollback()) {
-                try {
-                    UserTransaction transaction = Transaction.instance();
-                    if (transaction.isActiveOrMarkedRollback()
-                            || transaction.isRolledBack()) {
-                        log.debug("Rollback transaction");
-                        // mark it as rollback instead? see if SeamPhaseListener
-                        // will do the job properly
-                        transaction.rollback();
-                    }
-                } catch (Exception e) {
-                    log.error("Could not roll back transaction", e);
-                }
-            }
-        }
-        if (FacesLifecycle.getPhaseId() == PhaseId.RENDER_RESPONSE) {
-            if (response.isCommitted()) {
-                if (t instanceof ServletException) {
-                    throw (ServletException) t;
-                } else {
-                    throw new ServletException(t);
-                }
-            }
+    @Override
+    public void afterDispatch(Throwable t, HttpServletRequest request,
+            HttpServletResponse response) throws IOException, ServletException {
+        FacesContext context = FacesContext.getCurrentInstance();
+        FacesLifecycle.endRequest(context.getExternalContext());
+        if (context instanceof MockFacesContext) {
+            // do not release an actual FacesContext that would still exist
+            context.release();
         }
     }
 
-    private MockFacesContext createFacesContext(HttpServletRequest request,
+    protected MockFacesContext createFacesContext(HttpServletRequest request,
             HttpServletResponse response) {
-
         MockFacesContext mockFacesContext = new MockFacesContext(
                 new MockExternalContext(
                         request.getSession().getServletContext(), request,
