1 |
| |
2 |
| |
3 |
| |
4 |
| |
5 |
| |
6 |
| |
7 |
| package org.jboss.cache.transaction; |
8 |
| |
9 |
| import junit.framework.TestCase; |
10 |
| import org.jboss.cache.CacheImpl; |
11 |
| import org.jboss.cache.interceptors.OrderedSynchronizationHandler; |
12 |
| import org.jboss.cache.misc.TestingUtil; |
13 |
| import org.jgroups.JChannel; |
14 |
| import org.jgroups.blocks.RpcDispatcher; |
15 |
| |
16 |
| import javax.transaction.RollbackException; |
17 |
| import javax.transaction.Synchronization; |
18 |
| import javax.transaction.SystemException; |
19 |
| import javax.transaction.Transaction; |
20 |
| import javax.transaction.TransactionManager; |
21 |
| |
22 |
| |
23 |
| |
24 |
| |
25 |
| public class AbortionTest extends TestCase |
26 |
| { |
27 |
| private MyTC cache1, cache2, cache3; |
28 |
| |
29 |
3
| protected void setUp() throws Exception
|
30 |
| { |
31 |
3
| super.setUp();
|
32 |
3
| System.out.println("********* START: SET UP *************");
|
33 |
3
| cache1 = initCache(false);
|
34 |
3
| TestingUtil.sleepThread(1500);
|
35 |
3
| cache2 = initCache(false);
|
36 |
3
| cache3 = initCache(true);
|
37 |
3
| System.out.println("********* END: SET UP *************");
|
38 |
| } |
39 |
| |
40 |
| |
41 |
3
| protected void tearDown() throws Exception
|
42 |
| { |
43 |
3
| System.out.println("********* START: TEAR DOWN *************");
|
44 |
3
| destroyCache(cache3);
|
45 |
3
| destroyCache(cache2);
|
46 |
3
| destroyCache(cache1);
|
47 |
3
| cache1 = null;
|
48 |
3
| cache2 = null;
|
49 |
3
| cache3 = null;
|
50 |
3
| super.tearDown();
|
51 |
3
| System.out.println("********* END: TEAR DOWN *************");
|
52 |
| } |
53 |
| |
54 |
9
| private MyTC initCache(boolean notifying) throws Exception
|
55 |
| { |
56 |
9
| MyTC c = new MyTC();
|
57 |
9
| c.getConfiguration().setCacheMode("REPL_SYNC");
|
58 |
9
| c.getConfiguration().setClusterConfig(getJGroupsStack());
|
59 |
9
| c.getConfiguration().setFetchInMemoryState(false);
|
60 |
9
| if (!notifying)
|
61 |
| { |
62 |
6
| c.getConfiguration().setTransactionManagerLookupClass("org.jboss.cache.DummyTransactionManagerLookup");
|
63 |
| } |
64 |
| else |
65 |
| { |
66 |
3
| c.getConfiguration().setTransactionManagerLookupClass("org.jboss.cache.transaction.NotifyingTransactionManager");
|
67 |
| } |
68 |
9
| c.start();
|
69 |
9
| return c;
|
70 |
| } |
71 |
| |
72 |
| |
73 |
9
| private String getJGroupsStack()
|
74 |
| { |
75 |
| |
76 |
| |
77 |
| |
78 |
| |
79 |
| |
80 |
| |
81 |
| |
82 |
| |
83 |
| |
84 |
9
| return JChannel.DEFAULT_PROTOCOL_STACK;
|
85 |
| } |
86 |
| |
87 |
9
| private void destroyCache(MyTC c)
|
88 |
| { |
89 |
9
| if (c != null)
|
90 |
| { |
91 |
9
| c.stop();
|
92 |
9
| c.destroy();
|
93 |
| } |
94 |
| } |
95 |
| |
96 |
1
| public void testSyncCaches() throws Exception
|
97 |
| { |
98 |
1
| performTest(false, false);
|
99 |
| } |
100 |
| |
101 |
1
| public void testSyncCachesSyncCommitRollback() throws Exception
|
102 |
| { |
103 |
1
| performTest(true, false);
|
104 |
| } |
105 |
| |
106 |
| |
107 |
| |
108 |
| |
109 |
| |
110 |
| |
111 |
1
| public void testAbortBeforeCompletion() throws Exception
|
112 |
| { |
113 |
1
| performTest(true, true);
|
114 |
| } |
115 |
| |
116 |
3
| private void performTest(boolean syncCommitRollback, boolean abortBeforeCompletion) throws Exception
|
117 |
| { |
118 |
3
| cache1.getConfiguration().setSyncCommitPhase(syncCommitRollback);
|
119 |
3
| cache1.getConfiguration().setSyncRollbackPhase(syncCommitRollback);
|
120 |
3
| cache2.getConfiguration().setSyncCommitPhase(syncCommitRollback);
|
121 |
3
| cache2.getConfiguration().setSyncRollbackPhase(syncCommitRollback);
|
122 |
3
| cache3.getConfiguration().setSyncCommitPhase(syncCommitRollback);
|
123 |
3
| cache3.getConfiguration().setSyncRollbackPhase(syncCommitRollback);
|
124 |
| |
125 |
3
| TransactionManager mgr1 = cache1.getTransactionManager();
|
126 |
3
| TransactionManager mgr2 = cache2.getTransactionManager();
|
127 |
3
| NotifyingTransactionManager mgr3 = (NotifyingTransactionManager) cache3.getTransactionManager();
|
128 |
| |
129 |
3
| assertSame(mgr1, mgr2);
|
130 |
3
| assertNotSame(mgr1, mgr3);
|
131 |
3
| assertNotSame(mgr2, mgr3);
|
132 |
| |
133 |
3
| assertTrue(mgr1 instanceof DummyTransactionManager);
|
134 |
3
| assertTrue(mgr2 instanceof DummyTransactionManager);
|
135 |
3
| assertTrue(mgr3 instanceof NotifyingTransactionManager);
|
136 |
| |
137 |
| |
138 |
3
| cache1.put("/test", "key", "value");
|
139 |
| |
140 |
3
| assertEquals("value", cache1.get("/test", "key"));
|
141 |
3
| assertEquals("value", cache2.get("/test", "key"));
|
142 |
3
| assertEquals("value", cache3.get("/test", "key"));
|
143 |
| |
144 |
| |
145 |
3
| final boolean fAbortBeforeCompletion = abortBeforeCompletion;
|
146 |
3
| mgr3.notification = new NotifyingTransactionManager.Notification()
|
147 |
| { |
148 |
3
| public void notify(Transaction tx) throws SystemException, RollbackException
|
149 |
| { |
150 |
3
| final Transaction finalTx = tx;
|
151 |
3
| System.out.println("Notify called.");
|
152 |
| |
153 |
3
| Synchronization abort = new Synchronization()
|
154 |
| { |
155 |
| |
156 |
| Transaction t = finalTx; |
157 |
| |
158 |
3
| public void beforeCompletion()
|
159 |
| { |
160 |
3
| if (fAbortBeforeCompletion)
|
161 |
| { |
162 |
1
| cache3.myChannel.close();
|
163 |
1
| System.out.println("Returning from abort.beforeCompletion");
|
164 |
1
| try
|
165 |
| { |
166 |
1
| finalTx.setRollbackOnly();
|
167 |
| } |
168 |
| catch (SystemException e) |
169 |
| { |
170 |
0
| throw new RuntimeException("Unable to set rollback", e);
|
171 |
| } |
172 |
1
| throw new RuntimeException("Dummy exception");
|
173 |
| } |
174 |
| } |
175 |
| |
176 |
3
| public void afterCompletion(int i)
|
177 |
| { |
178 |
3
| if (!fAbortBeforeCompletion)
|
179 |
| { |
180 |
2
| cache3.myChannel.close();
|
181 |
2
| System.out.println("Returning from abort.afterCompletion");
|
182 |
2
| throw new RuntimeException("Dummy exception");
|
183 |
| } |
184 |
| } |
185 |
| }; |
186 |
| |
187 |
3
| OrderedSynchronizationHandler osh = OrderedSynchronizationHandler.getInstance(tx);
|
188 |
3
| osh.registerAtHead(abort);
|
189 |
3
| System.out.println("Added sync handler.");
|
190 |
| } |
191 |
| }; |
192 |
| |
193 |
3
| mgr1.begin();
|
194 |
3
| Transaction tx = mgr1.getTransaction();
|
195 |
3
| cache1.put("/test", "key", "value2");
|
196 |
3
| tx.commit();
|
197 |
| |
198 |
3
| TestingUtil.sleepThread(5000);
|
199 |
| |
200 |
| |
201 |
3
| assertEquals(0, cache1.getNumberOfLocksHeld());
|
202 |
3
| assertEquals(0, cache2.getNumberOfLocksHeld());
|
203 |
3
| assertEquals("put in transaction should NOT have been rolled back", "value2", cache1.get("/test", "key"));
|
204 |
3
| assertEquals("put in transaction should NOT have been rolled back", "value2", cache2.get("/test", "key"));
|
205 |
| |
206 |
| } |
207 |
| |
208 |
| |
209 |
| public static class MyTC extends CacheImpl |
210 |
| { |
211 |
| JChannel myChannel; |
212 |
| |
213 |
9
| public MyTC() throws Exception
|
214 |
| { |
215 |
9
| super();
|
216 |
| } |
217 |
| |
218 |
9
| public void start() throws Exception
|
219 |
| { |
220 |
9
| super.start();
|
221 |
9
| myChannel = channel;
|
222 |
| } |
223 |
| } |
224 |
| |
225 |
| } |