1
2
3
4
5
6
7 package org.mule.transaction;
8
9 import org.mule.api.transaction.Transaction;
10 import org.mule.api.transaction.TransactionException;
11 import org.mule.config.i18n.CoreMessages;
12
13 import org.apache.commons.logging.Log;
14 import org.apache.commons.logging.LogFactory;
15
16 public final class TransactionCoordination
17 {
18 protected static final Log logger = LogFactory.getLog(TransactionCoordination.class);
19
20 private static final TransactionCoordination instance = new TransactionCoordination();
21
22
23
24
25
26
27
28
29 private final ThreadLocal<Transaction> transactions = new ThreadLocal<Transaction>();
30
31
32 private final Object txCounterLock = new Object();
33
34
35 private int txCounter = 0;
36
37
38 private TransactionCoordination()
39 {
40 super();
41 }
42
43 public static TransactionCoordination getInstance()
44 {
45 return instance;
46 }
47
48 public Transaction getTransaction()
49 {
50 return transactions.get();
51 }
52
53 public void unbindTransaction(final Transaction transaction) throws TransactionException
54 {
55 Transaction oldTx = transactions.get();
56
57 if (oldTx instanceof TransactionCollection)
58 {
59
60 if (!((TransactionCollection) oldTx).getTxCollection().isEmpty())
61 {
62 return;
63 }
64 }
65
66 try
67 {
68 if (oldTx != null && !oldTx.equals(transaction))
69 {
70 throw new IllegalTransactionStateException(CoreMessages.transactionCannotUnbind());
71 }
72 }
73 finally
74 {
75 transactions.set(null);
76 logTransactionUnbound(transaction);
77 }
78 }
79
80 private void logTransactionUnbound(final Transaction transaction)
81 {
82
83 int txCounter = 0;
84 synchronized (txCounterLock)
85 {
86 if (this.txCounter > 0)
87 {
88 txCounter = --this.txCounter;
89 }
90 }
91
92 if (logger.isDebugEnabled())
93 {
94 logger.debug("Unbinding transaction (" + txCounter + ") " + transaction);
95 }
96 }
97
98 public void bindTransaction(final Transaction transaction) throws TransactionException
99 {
100 Transaction oldTx = transactions.get();
101
102 if (oldTx != null && !(oldTx instanceof TransactionCollection))
103 {
104 throw new IllegalTransactionStateException(CoreMessages.transactionAlreadyBound());
105 }
106
107 if (oldTx instanceof TransactionCollection)
108 {
109 TransactionCollection txCollection = (TransactionCollection) oldTx;
110 if (txCollection.getTxCollection().contains(transaction)) {
111
112 throw new IllegalTransactionStateException(CoreMessages.transactionAlreadyBound());
113 }
114 else
115 {
116
117 return;
118 }
119 }
120
121 transactions.set(transaction);
122 logTransactionBound(transaction);
123 }
124
125 private void logTransactionBound(final Transaction transaction)
126 {
127
128 int txCounter;
129 synchronized (txCounterLock)
130 {
131 txCounter = ++this.txCounter;
132 }
133
134 if (logger.isDebugEnabled())
135 {
136 logger.debug("Binding new transaction (" + txCounter + ") " + transaction);
137 }
138 }
139
140 public void clear()
141 {
142 transactions.remove();
143 }
144 }