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.Transaction;
11  import org.mule.api.transaction.TransactionException;
12  import org.mule.config.i18n.CoreMessages;
13  import org.mule.context.notification.TransactionNotification;
14  import org.mule.util.UUID;
15  
16  import java.text.MessageFormat;
17  
18  import org.apache.commons.logging.Log;
19  import org.apache.commons.logging.LogFactory;
20  
21  /**
22   * This base class provides low level features for transactions.
23   */
24  public abstract class AbstractTransaction implements Transaction
25  {
26  
27      protected final transient Log logger = LogFactory.getLog(getClass());
28  
29      protected String id = UUID.getUUID();
30  
31      protected MuleContext muleContext;
32  
33      protected AbstractTransaction(MuleContext muleContext)
34      {
35          this.muleContext = muleContext;
36      }
37  
38      public boolean isRollbackOnly() throws TransactionException
39      {
40          return getStatus() == STATUS_MARKED_ROLLBACK;
41      }
42  
43      public boolean isBegun() throws TransactionException
44      {
45          int status = getStatus();
46          return status != STATUS_NO_TRANSACTION && status != STATUS_UNKNOWN;
47      }
48  
49      public boolean isRolledBack() throws TransactionException
50      {
51          return getStatus() == STATUS_ROLLEDBACK;
52      }
53  
54      public boolean isCommitted() throws TransactionException
55      {
56          return getStatus() == STATUS_COMMITTED;
57      }
58  
59      public void begin() throws TransactionException
60      {
61          logger.debug("Beginning transaction");
62          doBegin();
63          TransactionCoordination.getInstance().bindTransaction(this);
64          fireNotification(new TransactionNotification(this, TransactionNotification.TRANSACTION_BEGAN));
65      }
66  
67      public void commit() throws TransactionException
68      {
69          try
70          {
71              logger.debug("Committing transaction " + this);
72  
73              if (isRollbackOnly())
74              {
75                  throw new IllegalTransactionStateException(CoreMessages.transactionMarkedForRollback());
76              }
77  
78              doCommit();
79              fireNotification(new TransactionNotification(this, TransactionNotification.TRANSACTION_COMMITTED));
80          }
81          finally
82          {
83              TransactionCoordination.getInstance().unbindTransaction(this);
84          }
85      }
86  
87      public void rollback() throws TransactionException
88      {
89          try
90          {
91              logger.debug("Rolling back transaction");
92              setRollbackOnly();
93              doRollback();
94              fireNotification(new TransactionNotification(this, TransactionNotification.TRANSACTION_ROLLEDBACK));
95          }
96          finally
97          {
98              unbindTransaction();
99          }
100     }
101 
102     /**
103      * Unbind this transaction when complete
104      */
105     protected void unbindTransaction() throws TransactionException
106     {
107         TransactionCoordination.getInstance().unbindTransaction(this);
108     }
109 
110 
111     /**
112      * Really begin the transaction. Note that resources are enlisted yet.
113      * 
114      * @throws TransactionException
115      */
116     protected abstract void doBegin() throws TransactionException;
117 
118     /**
119      * Commit the transaction on the underlying resource
120      * 
121      * @throws TransactionException
122      */
123     protected abstract void doCommit() throws TransactionException;
124 
125     /**
126      * Rollback the transaction on the underlying resource
127      * 
128      * @throws TransactionException
129      */
130     protected abstract void doRollback() throws TransactionException;
131 
132     /**
133      * Fires a server notification to all registered
134      * {@link org.mule.api.context.notification.TransactionNotificationListener}s.
135      *
136      */
137     protected void fireNotification(TransactionNotification notification)
138     {
139         // TODO profile this piece of code
140         muleContext.fireNotification(notification);
141     }
142 
143     public boolean isXA()
144     {
145         return false;
146     }
147 
148     public void resume() throws TransactionException
149     {
150         throw new IllegalTransactionStateException(CoreMessages.notMuleXaTransaction(this));
151     }
152 
153     public javax.transaction.Transaction suspend() throws TransactionException
154     {
155         throw new IllegalTransactionStateException(CoreMessages.notMuleXaTransaction(this));
156     }
157 
158     public String getId()
159     {
160         return id;
161     }
162 
163     @Override
164     public String toString()
165     {
166         int status;
167         try
168         {
169             status = getStatus();
170         }
171         catch (TransactionException e)
172         {
173             status = -1;
174         }
175         return MessageFormat.format("{0}[id={1} , status={2}]", getClass().getName(), id, status);
176     }
177 }