Home » geronimo-2.2-source-release » org.apache.geronimo.concurrent.handlers » [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.geronimo.concurrent.handlers;
   18   
   19   import java.util.Map;
   20   
   21   import javax.transaction.Status;
   22   import javax.transaction.SystemException;
   23   import javax.transaction.Transaction;
   24   import javax.transaction.TransactionManager;
   25   import javax.util.concurrent.ContextService;
   26   
   27   import org.apache.commons.logging.Log;
   28   import org.apache.commons.logging.LogFactory;
   29   import org.apache.geronimo.concurrent.ManagedContextHandler;
   30   
   31   /*
   32    * Managed context handler that for handling transactions. Follows 
   33    * Bean-Managed Transaction Demarcation rules as described in EJB 3.0 specification
   34    * 13.6.1 section.
   35    */
   36   public abstract class TransactionContextHandler implements ManagedContextHandler {
   37   
   38       protected final static Log LOG = LogFactory.getLog(TransactionContextHandler.class);
   39       
   40       protected final static String TRANSACTION_MANAGER = 
   41           TransactionContextHandler.class.getName() + ".transactionManager";
   42       
   43       protected final static String CLIENT_TRANSACTION = 
   44           TransactionContextHandler.class.getName() + ".clientTransaction";
   45                  
   46       private boolean isUseParentTransaction(Map<String, Object> threadContext) {
   47           Object useParentTransaction = 
   48               threadContext.get(ContextService.USE_PARENT_TRANSACTION);
   49           if (useParentTransaction instanceof String) {
   50               return Boolean.valueOf((String)useParentTransaction).booleanValue();
   51           } else if (useParentTransaction instanceof Boolean) {
   52               return Boolean.TRUE.equals(useParentTransaction);
   53           } else {
   54               return false;
   55           }
   56       }
   57       
   58       public void setContext(Map<String, Object> threadContext) {
   59           LOG.debug("setContext");
   60           
   61           if (!isUseParentTransaction(threadContext)) {                  
   62               suspendTransaction(threadContext);
   63           }
   64       }
   65       
   66       public void unsetContext(Map<String, Object> threadContext) {
   67           LOG.debug("unsetContext");
   68           
   69           if (!isUseParentTransaction(threadContext)) {                  
   70               resumeTransaction(threadContext);
   71           }
   72       }
   73       
   74       protected TransactionManager getTransactionManager(Map<String, Object> threadContext) {
   75           return (TransactionManager)threadContext.get(TRANSACTION_MANAGER);
   76       }
   77       
   78       protected void suspendTransaction(Map<String, Object> threadContext) {
   79           LOG.debug("suspendTransaction");
   80           
   81           TransactionManager manager = getTransactionManager(threadContext);
   82           
   83           try {
   84               Transaction clientTransaction = manager.suspend();
   85               if (clientTransaction != null) {
   86                   threadContext.put(CLIENT_TRANSACTION, clientTransaction);
   87               }
   88           } catch (SystemException e) {
   89               LOG.warn("Failed to suspend transaction", e);
   90           }        
   91       }
   92   
   93       public void resumeTransaction(Map<String, Object> threadContext) {
   94           LOG.debug("resumeTransaction");
   95           
   96           TransactionManager manager = getTransactionManager(threadContext);
   97                   
   98           try {
   99               /*
  100               * The Container must detect the case in which a transaction was started, but
  101               * not completed, in the business method, and handle it as follows:
  102               */
  103               Transaction transaction = manager.getTransaction();
  104   
  105               if (transaction == null) {
  106                   return;
  107               }
  108   
  109               if (transaction.getStatus() != Status.STATUS_ROLLEDBACK && 
  110                   transaction.getStatus() != Status.STATUS_COMMITTED) {
  111                   String message = "The task started a transaction but did not complete it.";
  112                   
  113                   LOG.error(message);
  114   
  115                   try {
  116                       manager.rollback();
  117                   } catch (Throwable t) {
  118                       // ignore
  119                   }
  120               }
  121   
  122           } catch (SystemException e) {
  123               LOG.warn("Error handling transaction", e);
  124           } finally {
  125               Transaction clientTransaction = 
  126                   (Transaction)threadContext.get(CLIENT_TRANSACTION);
  127               if (clientTransaction != null) {
  128                   try {
  129                       manager.resume(clientTransaction);
  130                   } catch (Exception  e) {
  131                       LOG.warn("Failed to resume transaction", e);
  132                   }
  133               }
  134           }
  135       }    
  136     
  137   }

Home » geronimo-2.2-source-release » org.apache.geronimo.concurrent.handlers » [javadoc | source]