Package org.apache.openejb.core.transaction

Source Code of org.apache.openejb.core.transaction.TransactionPolicy

/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.openejb.core.transaction;

import org.apache.openejb.ApplicationException;
import org.apache.openejb.InvalidateReferenceException;
import org.apache.openejb.SystemException;
import org.apache.openejb.core.ThreadContext;
import org.apache.openejb.core.Operation;
import org.apache.openejb.util.LogCategory;
import org.apache.openejb.util.Logger;

import javax.transaction.*;
import javax.ejb.EJBException;
import javax.ejb.EJBTransactionRolledbackException;

import java.rmi.RemoteException;

public abstract class TransactionPolicy {
    public Type getPolicyType() {
        return policyType;
    }

    public static enum Type {
        Mandatory,
        Never,
        NotSupported,
        Required,
        RequiresNew,
        Supports,
        BeanManaged;
    }


    private final Type policyType;
    protected final TransactionContainer container;
    private TransactionManager manager;

    protected final static Logger logger = Logger.getInstance(LogCategory.OPENEJB, "org.apache.openejb.util.resources");
    protected final static Logger txLogger = Logger.getInstance(LogCategory.TRANSACTION, "org.apache.openejb.util.resources");

    public TransactionPolicy(Type policyType, TransactionContainer container) {
        this.policyType = policyType;
        this.container = container;
    }

    public TransactionContainer getContainer() {
        return container;
    }

    public String policyToString() {
        return policyType.toString();
    }

    public abstract void handleApplicationException(Throwable appException, boolean rollback, TransactionContext context) throws ApplicationException, SystemException;

    public abstract void handleSystemException(Throwable sysException, Object instance, TransactionContext context) throws ApplicationException, SystemException;

    public abstract void beforeInvoke(Object bean, TransactionContext context) throws SystemException, ApplicationException;

    public abstract void afterInvoke(Object bean, TransactionContext context) throws ApplicationException, SystemException;

    protected void markTxRollbackOnly(Transaction tx) throws SystemException {
        try {
            if (tx != null) {
                tx.setRollbackOnly();
                if (txLogger.isInfoEnabled()) {
                    txLogger.info("TX " + policyToString() + ": setRollbackOnly() on transaction " + tx);
                }
            }
        } catch (javax.transaction.SystemException se) {
            logger.error("Exception during setRollbackOnly()", se);
            throw new SystemException(se);
        }
    }

    protected Transaction suspendTransaction(TransactionContext context) throws SystemException {
        try {
            Transaction tx = context.getTransactionManager().suspend();
            if (txLogger.isInfoEnabled()) {
                txLogger.info("TX " + policyToString() + ": Suspended transaction " + tx);
            }
            return tx;
        } catch (javax.transaction.SystemException se) {
            logger.error("Exception during suspend()", se);
            throw new SystemException(se);
        }
    }

    protected void resumeTransaction(TransactionContext context, Transaction tx) throws SystemException {
        try {
            if (tx == null) {
                if (txLogger.isInfoEnabled()) {
                    txLogger.info("TX " + policyToString() + ": No transaction to resume");
                }
            } else {
                if (txLogger.isInfoEnabled()) {
                    txLogger.info("TX " + policyToString() + ": Resuming transaction " + tx);
                }
                context.getTransactionManager().resume(tx);
            }
        } catch (InvalidTransactionException ite) {

            txLogger.error("Could not resume the client's transaction, the transaction is no longer valid: " + ite.getMessage());
            throw new SystemException(ite);
        } catch (IllegalStateException e) {

            txLogger.error("Could not resume the client's transaction: " + e.getMessage());
            throw new SystemException(e);
        } catch (javax.transaction.SystemException e) {

            txLogger.error("Could not resume the client's transaction: The transaction reported a system exception: " + e.getMessage());
            throw new SystemException(e);
        }
    }

    protected void commitTransaction(TransactionContext context, Transaction tx) throws SystemException, ApplicationException {
        try {
            if (txLogger.isInfoEnabled()) {
                txLogger.info("TX " + policyToString() + ": Committing transaction " + tx);
            }
            if (tx.equals(context.getTransactionManager().getTransaction())) {

                context.getTransactionManager().commit();
            } else {
                tx.commit();
            }
        } catch (RollbackException e) {

            txLogger.info("The transaction has been rolled back rather than commited: " + e.getMessage());
            // TODO can't set initCause on a TransactionRolledbackException, update the convertException and related code to handle something else
            Throwable txe = new javax.transaction.TransactionRolledbackException("Transaction was rolled back, presumably because setRollbackOnly was called during a synchronization: "+e.getMessage());
            throw new ApplicationException(txe);

        } catch (HeuristicMixedException e) {

            txLogger.info("A heuristic decision was made, some relevant updates have been committed while others have been rolled back: " + e.getMessage());
            throw new ApplicationException(new RemoteException("A heuristic decision was made, some relevant updates have been committed while others have been rolled back").initCause(e));

        } catch (HeuristicRollbackException e) {

            txLogger.info("A heuristic decision was made while commiting the transaction, some relevant updates have been rolled back: " + e.getMessage());
            throw new ApplicationException(new RemoteException("A heuristic decision was made while commiting the transaction, some relevant updates have been rolled back").initCause(e));

        } catch (SecurityException e) {

            txLogger.error("The current thread is not allowed to commit the transaction: " + e.getMessage());
            throw new SystemException(e);

        } catch (IllegalStateException e) {

            txLogger.error("The current thread is not associated with a transaction: " + e.getMessage());
            throw new SystemException(e);

        } catch (javax.transaction.SystemException e) {
            txLogger.error("The Transaction Manager has encountered an unexpected error condition while attempting to commit the transaction: " + e.getMessage());

            throw new SystemException(e);
        }
    }

    protected void rollbackTransaction(TransactionContext context, Transaction tx) throws SystemException {
        try {
            if (txLogger.isInfoEnabled()) {
                txLogger.info("TX " + policyToString() + ": Rolling back transaction " + tx);
            }
            if (tx.equals(context.getTransactionManager().getTransaction())) {

                context.getTransactionManager().rollback();
            } else {
                tx.rollback();
            }
        } catch (IllegalStateException e) {

            logger.error("The TransactionManager reported an exception while attempting to rollback the transaction: " + e.getMessage());
            throw new SystemException(e);

        } catch (javax.transaction.SystemException e) {

            logger.error("The TransactionManager reported an exception while attempting to rollback the transaction: " + e.getMessage());
            throw new SystemException(e);
        }
    }

    protected void throwAppExceptionToServer(Throwable appException) throws ApplicationException {
        throw new ApplicationException(appException);
    }

    protected void throwTxExceptionToServer(Throwable sysException) throws ApplicationException {
        /* Throw javax.transaction.TransactionRolledbackException to remote client */

        String message = "The transaction has been marked rollback only because the bean encountered a non-application exception :" + sysException.getClass().getName() + " : " + sysException.getMessage();
        TransactionRolledbackException txException = new TransactionRolledbackException(message, sysException);

        throw new InvalidateReferenceException(txException);

    }

    protected void throwExceptionToServer(Throwable sysException) throws ApplicationException {

        RemoteException re = new RemoteException("The bean encountered a non-application exception.", sysException);

        throw new InvalidateReferenceException(re);

    }

    protected void logSystemException(Throwable sysException, TransactionContext context) {
        Operation operation = context.callContext.getCurrentOperation();
        if (operation != null && operation.isCallback()){
            logger.error("startup.beanInstanceSystemExceptionThrown", sysException, sysException.getMessage());
        } else {
            logger.debug("startup.beanInstanceSystemExceptionThrown", sysException, sysException.getMessage());
        }
    }

    protected void discardBeanInstance(Object instance, ThreadContext callContext) {
        container.discardInstance(instance, callContext);
    }

    protected void beginTransaction(TransactionContext context) throws javax.transaction.SystemException {
        try {
            context.getTransactionManager().begin();
            if (txLogger.isInfoEnabled()) {
                txLogger.info("TX " + policyToString() + ": Started transaction " + context.getTransactionManager().getTransaction());
            }
        } catch (NotSupportedException nse) {
            logger.error("", nse);
        }
    }

    protected void handleCallbackException() {
    }
}
TOP

Related Classes of org.apache.openejb.core.transaction.TransactionPolicy

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.