Save This Page
Home » openejb-3.0-src » org.apache » openejb » core » transaction » [javadoc | source]
    1   /**
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    *
    9    *     http://www.apache.org/licenses/LICENSE-2.0
   10    *
   11    * Unless required by applicable law or agreed to in writing, software
   12    * distributed under the License is distributed on an "AS IS" BASIS,
   13    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14    * See the License for the specific language governing permissions and
   15    * limitations under the License.
   16    */
   17   package org.apache.openejb.core.transaction;
   18   
   19   import org.apache.openejb.ApplicationException;
   20   import org.apache.openejb.InvalidateReferenceException;
   21   import org.apache.openejb.SystemException;
   22   import org.apache.openejb.core.ThreadContext;
   23   import org.apache.openejb.core.Operation;
   24   import org.apache.openejb.util.LogCategory;
   25   import org.apache.openejb.util.Logger;
   26   
   27   import javax.transaction;
   28   import javax.ejb.EJBException;
   29   import javax.ejb.EJBTransactionRolledbackException;
   30   
   31   import java.rmi.RemoteException;
   32   
   33   public abstract class TransactionPolicy {
   34       public Type getPolicyType() {
   35           return policyType;
   36       }
   37   
   38       public static enum Type {
   39           Mandatory,
   40           Never,
   41           NotSupported,
   42           Required,
   43           RequiresNew,
   44           Supports,
   45           BeanManaged;
   46       }
   47   
   48   
   49       private final Type policyType;
   50       protected final TransactionContainer container;
   51       private TransactionManager manager;
   52   
   53       protected final static Logger logger = Logger.getInstance(LogCategory.OPENEJB, "org.apache.openejb.util.resources");
   54       protected final static Logger txLogger = Logger.getInstance(LogCategory.TRANSACTION, "org.apache.openejb.util.resources");
   55   
   56       public TransactionPolicy(Type policyType, TransactionContainer container) {
   57           this.policyType = policyType;
   58           this.container = container;
   59       }
   60   
   61       public TransactionContainer getContainer() {
   62           return container;
   63       }
   64   
   65       public String policyToString() {
   66           return policyType.toString();
   67       }
   68   
   69       public abstract void handleApplicationException(Throwable appException, boolean rollback, TransactionContext context) throws ApplicationException, SystemException;
   70   
   71       public abstract void handleSystemException(Throwable sysException, Object instance, TransactionContext context) throws ApplicationException, SystemException;
   72   
   73       public abstract void beforeInvoke(Object bean, TransactionContext context) throws SystemException, ApplicationException;
   74   
   75       public abstract void afterInvoke(Object bean, TransactionContext context) throws ApplicationException, SystemException;
   76   
   77       protected void markTxRollbackOnly(Transaction tx) throws SystemException {
   78           try {
   79               if (tx != null) {
   80                   tx.setRollbackOnly();
   81                   if (txLogger.isInfoEnabled()) {
   82                       txLogger.info("TX " + policyToString() + ": setRollbackOnly() on transaction " + tx);
   83                   }
   84               }
   85           } catch (javax.transaction.SystemException se) {
   86               logger.error("Exception during setRollbackOnly()", se);
   87               throw new SystemException(se);
   88           }
   89       }
   90   
   91       protected Transaction suspendTransaction(TransactionContext context) throws SystemException {
   92           try {
   93               Transaction tx = context.getTransactionManager().suspend();
   94               if (txLogger.isInfoEnabled()) {
   95                   txLogger.info("TX " + policyToString() + ": Suspended transaction " + tx);
   96               }
   97               return tx;
   98           } catch (javax.transaction.SystemException se) {
   99               logger.error("Exception during suspend()", se);
  100               throw new SystemException(se);
  101           }
  102       }
  103   
  104       protected void resumeTransaction(TransactionContext context, Transaction tx) throws SystemException {
  105           try {
  106               if (tx == null) {
  107                   if (txLogger.isInfoEnabled()) {
  108                       txLogger.info("TX " + policyToString() + ": No transaction to resume");
  109                   }
  110               } else {
  111                   if (txLogger.isInfoEnabled()) {
  112                       txLogger.info("TX " + policyToString() + ": Resuming transaction " + tx);
  113                   }
  114                   context.getTransactionManager().resume(tx);
  115               }
  116           } catch (InvalidTransactionException ite) {
  117   
  118               txLogger.error("Could not resume the client's transaction, the transaction is no longer valid: " + ite.getMessage());
  119               throw new SystemException(ite);
  120           } catch (IllegalStateException e) {
  121   
  122               txLogger.error("Could not resume the client's transaction: " + e.getMessage());
  123               throw new SystemException(e);
  124           } catch (javax.transaction.SystemException e) {
  125   
  126               txLogger.error("Could not resume the client's transaction: The transaction reported a system exception: " + e.getMessage());
  127               throw new SystemException(e);
  128           }
  129       }
  130   
  131       protected void commitTransaction(TransactionContext context, Transaction tx) throws SystemException, ApplicationException {
  132           try {
  133               if (txLogger.isInfoEnabled()) {
  134                   txLogger.info("TX " + policyToString() + ": Committing transaction " + tx);
  135               }
  136               if (tx.equals(context.getTransactionManager().getTransaction())) {
  137   
  138                   context.getTransactionManager().commit();
  139               } else {
  140                   tx.commit();
  141               }
  142           } catch (RollbackException e) {
  143   
  144               txLogger.info("The transaction has been rolled back rather than commited: " + e.getMessage());
  145               // TODO can't set initCause on a TransactionRolledbackException, update the convertException and related code to handle something else 
  146               Throwable txe = new javax.transaction.TransactionRolledbackException("Transaction was rolled back, presumably because setRollbackOnly was called during a synchronization: "+e.getMessage());
  147               throw new ApplicationException(txe);
  148   
  149           } catch (HeuristicMixedException e) {
  150   
  151               txLogger.info("A heuristic decision was made, some relevant updates have been committed while others have been rolled back: " + e.getMessage());
  152               throw new ApplicationException(new RemoteException("A heuristic decision was made, some relevant updates have been committed while others have been rolled back").initCause(e));
  153   
  154           } catch (HeuristicRollbackException e) {
  155   
  156               txLogger.info("A heuristic decision was made while commiting the transaction, some relevant updates have been rolled back: " + e.getMessage());
  157               throw new ApplicationException(new RemoteException("A heuristic decision was made while commiting the transaction, some relevant updates have been rolled back").initCause(e));
  158   
  159           } catch (SecurityException e) {
  160   
  161               txLogger.error("The current thread is not allowed to commit the transaction: " + e.getMessage());
  162               throw new SystemException(e);
  163   
  164           } catch (IllegalStateException e) {
  165   
  166               txLogger.error("The current thread is not associated with a transaction: " + e.getMessage());
  167               throw new SystemException(e);
  168   
  169           } catch (javax.transaction.SystemException e) {
  170               txLogger.error("The Transaction Manager has encountered an unexpected error condition while attempting to commit the transaction: " + e.getMessage());
  171   
  172               throw new SystemException(e);
  173           }
  174       }
  175   
  176       protected void rollbackTransaction(TransactionContext context, Transaction tx) throws SystemException {
  177           try {
  178               if (txLogger.isInfoEnabled()) {
  179                   txLogger.info("TX " + policyToString() + ": Rolling back transaction " + tx);
  180               }
  181               if (tx.equals(context.getTransactionManager().getTransaction())) {
  182   
  183                   context.getTransactionManager().rollback();
  184               } else {
  185                   tx.rollback();
  186               }
  187           } catch (IllegalStateException e) {
  188   
  189               logger.error("The TransactionManager reported an exception while attempting to rollback the transaction: " + e.getMessage());
  190               throw new SystemException(e);
  191   
  192           } catch (javax.transaction.SystemException e) {
  193   
  194               logger.error("The TransactionManager reported an exception while attempting to rollback the transaction: " + e.getMessage());
  195               throw new SystemException(e);
  196           }
  197       }
  198   
  199       protected void throwAppExceptionToServer(Throwable appException) throws ApplicationException {
  200           throw new ApplicationException(appException);
  201       }
  202   
  203       protected void throwTxExceptionToServer(Throwable sysException) throws ApplicationException {
  204           /* Throw javax.transaction.TransactionRolledbackException to remote client */
  205   
  206           String message = "The transaction has been marked rollback only because the bean encountered a non-application exception :" + sysException.getClass().getName() + " : " + sysException.getMessage();
  207           TransactionRolledbackException txException = new TransactionRolledbackException(message, sysException);
  208   
  209           throw new InvalidateReferenceException(txException);
  210   
  211       }
  212   
  213       protected void throwExceptionToServer(Throwable sysException) throws ApplicationException {
  214   
  215           RemoteException re = new RemoteException("The bean encountered a non-application exception.", sysException);
  216   
  217           throw new InvalidateReferenceException(re);
  218   
  219       }
  220   
  221       protected void logSystemException(Throwable sysException, TransactionContext context) {
  222           Operation operation = context.callContext.getCurrentOperation();
  223           if (operation != null && operation.isCallback()){
  224               logger.error("startup.beanInstanceSystemExceptionThrown", sysException, sysException.getMessage());
  225           } else {
  226               logger.debug("startup.beanInstanceSystemExceptionThrown", sysException, sysException.getMessage());
  227           }
  228       }
  229   
  230       protected void discardBeanInstance(Object instance, ThreadContext callContext) {
  231           container.discardInstance(instance, callContext);
  232       }
  233   
  234       protected void beginTransaction(TransactionContext context) throws javax.transaction.SystemException {
  235           try {
  236               context.getTransactionManager().begin();
  237               if (txLogger.isInfoEnabled()) {
  238                   txLogger.info("TX " + policyToString() + ": Started transaction " + context.getTransactionManager().getTransaction());
  239               }
  240           } catch (NotSupportedException nse) {
  241               logger.error("", nse);
  242           }
  243       }
  244   
  245       protected void handleCallbackException() {
  246       }
  247   }
  248   

Save This Page
Home » openejb-3.0-src » org.apache » openejb » core » transaction » [javadoc | source]