View Javadoc
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.mule.api.MuleContext;
10  import org.mule.api.transaction.TransactionException;
11  import org.mule.config.i18n.CoreMessages;
12  
13  import java.text.MessageFormat;
14  
15  import javax.transaction.Status;
16  import javax.transaction.Synchronization;
17  
18  /**
19   * <code>ExternalXaTransaction</code> represents an external XA transaction in Mule.
20   */
21  public class ExternalXaTransaction extends XaTransaction
22  {
23      public ExternalXaTransaction(MuleContext muleContext)
24      {
25          super(muleContext);
26      }
27  
28      protected void doBegin() throws TransactionException
29      {
30          if (txManager == null)
31          {
32              throw new IllegalStateException(
33                      CoreMessages.objectNotRegistered("javax.transaction.TransactionManager", "Transaction Manager").getMessage());
34          }
35  
36          try
37          {
38              synchronized (this)
39              {
40                  transaction = txManager.getTransaction();
41                  transaction.registerSynchronization(new ExternalTransaction(muleContext));
42              }
43          }
44          catch (Exception e)
45          {
46              throw new TransactionException(CoreMessages.cannotStartTransaction("XA"), e);
47          }
48      }
49  
50      /**
51       * This class is notified when an external transaction is complete and cleans up
52       * Mule-specific resources
53       */
54      class ExternalTransaction extends AbstractTransaction implements Synchronization
55      {
56          ExternalTransaction(MuleContext muleContext)
57          {
58              super(muleContext);
59          }
60          
61          /** Nothing to do */
62          public void beforeCompletion()
63          {
64          }
65  
66          /** Clean up mule resources */
67          public void afterCompletion(int status)
68          {
69              boolean commit = status == Status.STATUS_COMMITTED;
70  
71              try
72              {
73                  if (commit)
74                  {
75                      commit();
76                  }
77                  else
78                  {
79                      rollback();
80                  }
81              }
82              catch (TransactionException ex)
83              {
84                  logger.warn(MessageFormat.format(
85                      "Exception while {0} an external transaction {1}", commit ? "committing" : "rolling back", this), ex);
86              }
87          }
88  
89          @Override
90          protected void unbindTransaction()
91          {
92              // no-op -- already unbound in TransactionTemplate
93          }
94  
95          @Override
96          protected void doCommit()
97          {
98              delistResources();
99              closeResources();
100             transaction = null;
101         }
102 
103         @Override
104         protected void doRollback()
105         {
106             closeResources();
107             transaction = null;
108         }
109 
110         @Override
111         protected void doBegin()
112         {
113         }
114 
115         @Override
116         public boolean isRollbackOnly() throws TransactionException
117         {
118             return ExternalXaTransaction.this.isRollbackOnly();
119         }
120 
121         public int getStatus() throws TransactionException
122         {
123             return ExternalXaTransaction.this.getStatus();
124         }
125 
126         public Object getResource(Object key)
127         {
128             return ExternalXaTransaction.this.getResource(key);
129         }
130 
131         public boolean hasResource(Object key)
132         {
133             return ExternalXaTransaction.this.hasResource(key);
134         }
135 
136         public void bindResource(Object key, Object resource) throws TransactionException
137         {
138         }
139 
140         public void setRollbackOnly() throws TransactionException
141         {
142         }
143     }
144 }