1
2
3
4
5
6
7
8
9
10
11 package org.mule.tck;
12
13 import org.mule.MuleManager;
14 import org.mule.impl.DefaultExceptionStrategy;
15 import org.mule.impl.MuleTransactionConfig;
16 import org.mule.transaction.TransactionCallback;
17 import org.mule.transaction.TransactionTemplate;
18 import org.mule.transaction.XaTransaction;
19 import org.mule.transaction.XaTransactionFactory;
20 import org.mule.umo.UMOTransactionConfig;
21 import org.mule.umo.manager.UMOTransactionManagerFactory;
22
23 import javax.transaction.Status;
24 import javax.transaction.Transaction;
25 import javax.transaction.TransactionManager;
26
27
28
29
30
31 public abstract class AbstractTxThreadAssociationTestCase extends AbstractMuleTestCase
32 {
33
34 private TransactionManager tm;
35 protected static final int TRANSACTION_TIMEOUT_SECONDS = 3;
36
37 protected void doSetUp() throws Exception
38 {
39 super.doSetUp();
40 UMOTransactionManagerFactory factory = getTransactionManagerFactory();
41 tm = factory.create();
42 assertNotNull("Transaction Manager should be available.", tm);
43 assertNull("There sould be no current transaction associated.", tm.getTransaction());
44 }
45
46 public void testTxHandleCommitKeepsThreadAssociation() throws Exception
47 {
48
49 tm.setTransactionTimeout(TRANSACTION_TIMEOUT_SECONDS);
50 tm.begin();
51
52 Transaction tx = tm.getTransaction();
53 assertNotNull("Transaction should have started.", tx);
54 assertEquals("TX should have been active", Status.STATUS_ACTIVE, tx.getStatus());
55
56 tx.commit();
57
58 tx = tm.getTransaction();
59 assertNotNull("Committing via TX handle should NOT disassociated TX from the current thread.",
60 tx);
61 assertEquals("TX status should have been COMMITTED.", Status.STATUS_COMMITTED, tx.getStatus());
62
63
64
65 Transaction suspended = tm.suspend();
66 assertTrue("Wrong TX suspended?.", suspended.equals(tx));
67 assertNull("TX should've been disassociated from the thread.", tm.getTransaction());
68
69
70 tm.resume(null);
71
72
73 assertNull(tm.getTransaction());
74 }
75
76 public void testTxManagerCommitDissassociatesThread() throws Exception
77 {
78
79 tm.setTransactionTimeout(TRANSACTION_TIMEOUT_SECONDS);
80 tm.begin();
81
82 Transaction tx = tm.getTransaction();
83 assertNotNull("Transaction should have started.", tx);
84 assertEquals("TX should have been active", Status.STATUS_ACTIVE, tx.getStatus());
85
86 tm.commit();
87
88 assertNull("Committing via TX Manager should have disassociated TX from the current thread.",
89 tm.getTransaction());
90 }
91
92 public void testTxManagerRollbackDissassociatesThread() throws Exception
93 {
94
95 tm.setTransactionTimeout(TRANSACTION_TIMEOUT_SECONDS);
96 tm.begin();
97
98 Transaction tx = tm.getTransaction();
99 assertNotNull("Transaction should have started.", tx);
100 assertEquals("TX should have been active", Status.STATUS_ACTIVE, tx.getStatus());
101
102 tm.rollback();
103
104 assertNull("Committing via TX Manager should have disassociated TX from the current thread.",
105 tm.getTransaction());
106 }
107
108
109
110
111
112
113 public void testAlwaysBeginXaTransactionSuspendResume() throws Exception
114 {
115 MuleManager.getInstance().setTransactionManager(tm);
116 assertNull("There sould be no current transaction associated.", tm.getTransaction());
117
118
119 tm.setTransactionTimeout(TRANSACTION_TIMEOUT_SECONDS);
120
121
122 UMOTransactionConfig config = new MuleTransactionConfig();
123 config.setFactory(new XaTransactionFactory());
124 config.setAction(UMOTransactionConfig.ACTION_ALWAYS_BEGIN);
125 TransactionTemplate template = new TransactionTemplate(config, new DefaultExceptionStrategy());
126
127
128 final UMOTransactionConfig nestedConfig = new MuleTransactionConfig();
129 nestedConfig.setFactory(new XaTransactionFactory());
130 nestedConfig.setAction(UMOTransactionConfig.ACTION_ALWAYS_BEGIN);
131
132
133 template.execute(new TransactionCallback()
134 {
135 public Object doInTransaction() throws Exception
136 {
137
138
139 TransactionTemplate nestedTemplate =
140 new TransactionTemplate(nestedConfig, new DefaultExceptionStrategy());
141 final Transaction firstTx = tm.getTransaction();
142 assertNotNull(firstTx);
143 assertEquals(firstTx.getStatus(), Status.STATUS_ACTIVE);
144 return nestedTemplate.execute(new TransactionCallback()
145 {
146 public Object doInTransaction() throws Exception
147 {
148 Transaction secondTx = tm.getTransaction();
149 assertNotNull(secondTx);
150 assertEquals(firstTx.getStatus(), Status.STATUS_ACTIVE);
151 assertEquals(secondTx.getStatus(), Status.STATUS_ACTIVE);
152 try
153 {
154 tm.resume(firstTx);
155 fail("Second transaction must be active");
156 }
157 catch (java.lang.IllegalStateException e)
158 {
159
160
161
162
163 }
164 try
165 {
166 Transaction currentTx = tm.suspend();
167 assertTrue(currentTx.equals(secondTx));
168 tm.resume(firstTx);
169 assertEquals(firstTx, tm.getTransaction());
170 assertEquals(firstTx.getStatus(), Status.STATUS_ACTIVE);
171 assertEquals(secondTx.getStatus(), Status.STATUS_ACTIVE);
172 Transaction a = tm.suspend();
173 assertTrue(a.equals(firstTx));
174 tm.resume(secondTx);
175 }
176 catch (Exception e)
177 {
178 fail("Error: " + e);
179 }
180
181
182 return null;
183 }
184 });
185 }
186 });
187 assertNull("Committing via TX Manager should have disassociated TX from the current thread.",
188 tm.getTransaction());
189 }
190
191
192
193
194
195
196 public void testXaTransactionTermination() throws Exception
197 {
198 MuleManager.getInstance().setTransactionManager(tm);
199 assertNull("There sould be no current transaction associated.", tm.getTransaction());
200
201
202 tm.setTransactionTimeout(TRANSACTION_TIMEOUT_SECONDS);
203
204 XaTransaction muleTx = new XaTransaction();
205 assertFalse(muleTx.isBegun());
206 assertEquals(Status.STATUS_NO_TRANSACTION, muleTx.getStatus());
207 muleTx.begin();
208
209 assertTrue(muleTx.isBegun());
210
211 muleTx.commit();
212
213 Transaction jtaTx = tm.getTransaction();
214 assertNull("Committing via TX Manager should have disassociated TX from the current thread.", jtaTx);
215 assertEquals(Status.STATUS_NO_TRANSACTION, muleTx.getStatus());
216 }
217
218
219
220
221
222
223
224 public void testNoNestedTxStarted() throws Exception
225 {
226 MuleManager.getInstance().setTransactionManager(tm);
227 assertNull("There sould be no current transaction associated.", tm.getTransaction());
228
229
230 tm.setTransactionTimeout(TRANSACTION_TIMEOUT_SECONDS);
231
232
233 UMOTransactionConfig config = new MuleTransactionConfig();
234 config.setFactory(new XaTransactionFactory());
235 config.setAction(UMOTransactionConfig.ACTION_ALWAYS_BEGIN);
236 TransactionTemplate template = new TransactionTemplate(config, new DefaultExceptionStrategy());
237
238
239 final UMOTransactionConfig nestedConfig = new MuleTransactionConfig();
240 nestedConfig.setFactory(new XaTransactionFactory());
241 nestedConfig.setAction(UMOTransactionConfig.ACTION_BEGIN_OR_JOIN);
242
243
244 template.execute(new TransactionCallback()
245 {
246 public Object doInTransaction() throws Exception
247 {
248
249
250 TransactionTemplate nestedTemplate =
251 new TransactionTemplate(nestedConfig, new DefaultExceptionStrategy());
252 return nestedTemplate.execute(new TransactionCallback()
253 {
254 public Object doInTransaction() throws Exception
255 {
256
257 return null;
258 }
259 });
260 }
261 });
262 }
263
264
265 protected TransactionManager getTransactionManager()
266 {
267 return tm;
268 }
269
270 protected abstract UMOTransactionManagerFactory getTransactionManagerFactory();
271
272 }