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