PageRenderTime 35ms CodeModel.GetById 25ms app.highlight 9ms RepoModel.GetById 0ms app.codeStats 0ms

/jboss-as-7.1.1.Final/ejb3/src/main/java/org/jboss/as/ejb3/tx/EjbBMTInterceptor.java

#
Java | 120 lines | 76 code | 12 blank | 32 comment | 7 complexity | 030cd0b50f169e495d43f35c6e7ad045 MD5 | raw file
Possible License(s): LGPL-2.1, Apache-2.0
  1/*
  2 * JBoss, Home of Professional Open Source.
  3 * Copyright (c) 2011, Red Hat, Inc., and individual contributors
  4 * as indicated by the @author tags. See the copyright.txt file in the
  5 * distribution for a full listing of individual contributors.
  6 *
  7 * This is free software; you can redistribute it and/or modify it
  8 * under the terms of the GNU Lesser General Public License as
  9 * published by the Free Software Foundation; either version 2.1 of
 10 * the License, or (at your option) any later version.
 11 *
 12 * This software is distributed in the hope that it will be useful,
 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 15 * Lesser General Public License for more details.
 16 *
 17 * You should have received a copy of the GNU Lesser General Public
 18 * License along with this software; if not, write to the Free
 19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 21 */
 22package org.jboss.as.ejb3.tx;
 23
 24import javax.ejb.EJBException;
 25import javax.transaction.Status;
 26import javax.transaction.SystemException;
 27import javax.transaction.TransactionManager;
 28
 29import org.jboss.as.ee.component.Component;
 30import org.jboss.as.ee.component.ComponentInstanceInterceptorFactory;
 31import org.jboss.as.ejb3.component.EJBComponent;
 32import org.jboss.invocation.Interceptor;
 33import org.jboss.invocation.InterceptorContext;
 34import org.jboss.invocation.InterceptorFactory;
 35import org.jboss.invocation.InterceptorFactoryContext;
 36import org.jboss.logging.Logger;
 37
 38/**
 39 * EJB 3 13.6.1:
 40 * If a stateless session bean instance starts a transaction in a business method or interceptor method, it
 41 * must commit the transaction before the business method (or all its interceptor methods) returns.
 42 *
 43 * @author <a href="mailto:carlo.dewolf@jboss.com">Carlo de Wolf</a>
 44 * @version $Revision: $
 45 */
 46public class EjbBMTInterceptor extends BMTInterceptor {
 47    private static final Logger log = Logger.getLogger(EjbBMTInterceptor.class);
 48
 49    public static final InterceptorFactory FACTORY = new ComponentInstanceInterceptorFactory() {
 50        @Override
 51        protected Interceptor create(final Component component, final InterceptorFactoryContext context) {
 52            return new EjbBMTInterceptor((EJBComponent) component);
 53        }
 54    };
 55
 56    EjbBMTInterceptor(final EJBComponent component) {
 57        super(component);
 58    }
 59
 60    private void checkStatelessDone(final EJBComponent component, final InterceptorContext invocation, final TransactionManager tm, Throwable ex) throws Exception {
 61        int status = Status.STATUS_NO_TRANSACTION;
 62
 63        try {
 64            status = tm.getStatus();
 65        } catch (SystemException sex) {
 66            log.error("Failed to get status", sex);
 67        }
 68
 69        switch (status) {
 70            case Status.STATUS_ACTIVE:
 71            case Status.STATUS_COMMITTING:
 72            case Status.STATUS_MARKED_ROLLBACK:
 73            case Status.STATUS_PREPARING:
 74            case Status.STATUS_ROLLING_BACK:
 75                try {
 76                    tm.rollback();
 77                } catch (Exception sex) {
 78                    log.error("Failed to rollback", sex);
 79                }
 80                // fall through...
 81            case Status.STATUS_PREPARED:
 82                String msg = "EJB 3.1 FR 13.3.3: BMT bean " + component.getComponentName()
 83                        + " should complete transaction before returning.";
 84                log.error(msg);
 85                if (ex instanceof Exception) {
 86                    throw new EJBException(msg, (Exception) ex);
 87                } else {
 88                    throw new EJBException(msg, new RuntimeException(ex));
 89                }
 90        }
 91        // the instance interceptor will discard the instance
 92        if (ex != null)
 93            throw this.handleException(invocation, ex);
 94    }
 95
 96
 97    @Override
 98    protected Object handleInvocation(final InterceptorContext invocation) throws Exception {
 99        final EJBComponent ejbComponent = getComponent();
100        TransactionManager tm = ejbComponent.getTransactionManager();
101        assert tm.getTransaction() == null : "can't handle BMT transaction, there is a transaction active";
102
103        boolean exceptionThrown = false;
104        try {
105            return invocation.proceed();
106        } catch (Throwable ex) {
107            exceptionThrown = true;
108            checkStatelessDone(ejbComponent, invocation, tm, ex);
109            //we should never get here, as checkStatelessDone should re-throw
110            throw (Exception)ex;
111        } finally {
112            try {
113                if (!exceptionThrown) checkStatelessDone(ejbComponent, invocation, tm, null);
114            } finally {
115                tm.suspend();
116            }
117        }
118    }
119
120}