Coverage Report - org.mule.transaction.TransactionTemplate
 
Classes in this File Line Coverage Branch Coverage Complexity
TransactionTemplate
0%
0/65
0%
0/58
0
 
 1  
 /*
 2  
  * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
 3  
  * The software in this package is published under the terms of the CPAL v1.0
 4  
  * license, a copy of which has been included with this distribution in the
 5  
  * LICENSE.txt file.
 6  
  */
 7  
 package org.mule.transaction;
 8  
 
 9  
 import org.apache.commons.logging.Log;
 10  
 import org.apache.commons.logging.LogFactory;
 11  
 import org.mule.api.MuleContext;
 12  
 import org.mule.api.transaction.*;
 13  
 import org.mule.config.i18n.CoreMessages;
 14  
 
 15  
 public class TransactionTemplate<T>
 16  
 {
 17  
 
 18  0
     private static final Log logger = LogFactory.getLog(TransactionTemplate.class);
 19  
 
 20  
     private final TransactionConfig config;
 21  
     private final MuleContext context;
 22  
 
 23  
     public TransactionTemplate(TransactionConfig config, MuleContext context)
 24  0
     {
 25  0
         this.config = config;
 26  0
         this.context = context;
 27  0
     }
 28  
 
 29  
     public T execute(TransactionCallback<T> callback) throws Exception
 30  
     {
 31  
         //if we want to skip TT
 32  0
         if (config == null)
 33  
         {
 34  0
             return callback.doInTransaction();
 35  
         }
 36  
 
 37  0
         Transaction joinedExternal = null;
 38  0
         byte action = (config != null) ? config.getAction() : TransactionConfig.ACTION_DEFAULT;
 39  0
         Transaction tx = TransactionCoordination.getInstance().getTransaction();
 40  0
         if (tx == null && context != null && config != null && config.isInteractWithExternal())
 41  
         {
 42  
 
 43  0
             TransactionFactory tmFactory = config.getFactory();
 44  0
             if (tmFactory instanceof ExternalTransactionAwareTransactionFactory)
 45  
             {
 46  0
                 ExternalTransactionAwareTransactionFactory extmFactory =
 47  
                     (ExternalTransactionAwareTransactionFactory) tmFactory;
 48  0
                 joinedExternal = tx = extmFactory.joinExternalTransaction(context);
 49  
             }
 50  
         }
 51  
 
 52  0
         Transaction suspendedXATx = null;
 53  
 
 54  0
         if (action == TransactionConfig.ACTION_NEVER && tx != null)
 55  
         {
 56  0
             throw new IllegalTransactionStateException(
 57  
                 CoreMessages.transactionAvailableButActionIs("Never"));
 58  
         }
 59  0
         else if ((action == TransactionConfig.ACTION_NONE || action == TransactionConfig.ACTION_ALWAYS_BEGIN)
 60  
                    && tx != null)
 61  
         {
 62  0
             if (logger.isDebugEnabled())
 63  
             {
 64  0
                 logger.debug(action + ", " + "current TX: " + tx);
 65  
             }
 66  
 
 67  0
             if (tx.isXA())
 68  
             {
 69  
                 // suspend current transaction
 70  0
                 suspendedXATx = tx;
 71  0
                 suspendXATransaction(suspendedXATx);
 72  
             }
 73  
             else
 74  
             {
 75  
                 // commit/rollback
 76  0
                 resolveTransaction(tx);
 77  
             }
 78  
             //transaction will be started below
 79  0
             tx = null;
 80  
         }
 81  0
         else if (action == TransactionConfig.ACTION_ALWAYS_JOIN && tx == null)
 82  
         {
 83  0
             throw new IllegalTransactionStateException(
 84  
                 CoreMessages.transactionNotAvailableButActionIs("Always Join"));
 85  
         }
 86  
 
 87  0
         if (action == TransactionConfig.ACTION_ALWAYS_BEGIN
 88  
             || (action == TransactionConfig.ACTION_BEGIN_OR_JOIN && tx == null))
 89  
         {
 90  0
             logger.debug("Beginning transaction");
 91  0
             tx = config.getFactory().beginTransaction(context);
 92  0
             logger.debug("Transaction successfully started: " + tx);
 93  
         }
 94  
         else
 95  
         {
 96  0
             tx = null;
 97  
         }
 98  
 
 99  0
         T result = callback.doInTransaction();
 100  0
         if (tx != null)
 101  
         {
 102  
             //verify that transaction is still active
 103  0
             tx = TransactionCoordination.getInstance().getTransaction();
 104  
         }
 105  0
         if (tx != null)
 106  
         {
 107  0
             resolveTransaction(tx);
 108  
         }
 109  0
         if (suspendedXATx != null)
 110  
         {
 111  0
             resumeXATransaction(suspendedXATx);
 112  0
             tx = suspendedXATx;
 113  
         }
 114  0
         if (joinedExternal != null)
 115  
         {
 116  0
             TransactionCoordination.getInstance().unbindTransaction(joinedExternal);
 117  
         }
 118  0
         return result;
 119  
     }
 120  
 
 121  
     protected void resolveTransaction(Transaction tx) throws TransactionException
 122  
     {
 123  0
         if (tx.isRollbackOnly())
 124  
         {
 125  0
             if (logger.isDebugEnabled())
 126  
             {
 127  0
                 logger.debug("Transaction has been marked rollbackOnly, rolling it back: " + tx);
 128  
             }
 129  0
             tx.rollback();
 130  
         } else
 131  
         {
 132  0
             if (logger.isDebugEnabled())
 133  
             {
 134  0
                 logger.debug("Committing transaction " + tx);
 135  
             }
 136  0
             tx.commit();
 137  
         }
 138  0
     }
 139  
 
 140  
     protected void suspendXATransaction(Transaction tx) throws TransactionException
 141  
     {
 142  0
         if (logger.isDebugEnabled())
 143  
         {
 144  0
             logger.debug("Suspending " + tx);
 145  
         }
 146  
 
 147  0
         tx.suspend();
 148  
 
 149  0
         if (logger.isDebugEnabled())
 150  
         {
 151  0
             logger.debug("Successfully suspended " + tx);
 152  0
             logger.debug("Unbinding the following TX from the current context: " + tx);
 153  
         }
 154  
 
 155  0
         TransactionCoordination.getInstance().unbindTransaction(tx);
 156  0
     }
 157  
 
 158  
     protected void resumeXATransaction(Transaction tx) throws TransactionException
 159  
     {
 160  0
         if (logger.isDebugEnabled())
 161  
         {
 162  0
             logger.debug("Re-binding and Resuming " + tx);
 163  
         }
 164  
 
 165  0
         TransactionCoordination.getInstance().bindTransaction(tx);
 166  0
         tx.resume();
 167  0
     }
 168  
 
 169  
 }
 170