View Javadoc

1   package net.sf.ehcache.store;
2   
3   import static org.junit.Assert.assertEquals;
4   import static org.junit.Assert.assertFalse;
5   import static org.junit.Assert.assertNotNull;
6   import static org.junit.Assert.assertNull;
7   import static org.junit.Assert.assertTrue;
8   import static org.junit.Assert.fail;
9   
10  import javax.transaction.RollbackException;
11  import javax.transaction.Transaction;
12  import javax.transaction.TransactionManager;
13  
14  import net.sf.ehcache.Cache;
15  import net.sf.ehcache.CacheManager;
16  import net.sf.ehcache.Element;
17  import net.sf.ehcache.concurrent.CacheLockProvider;
18  import net.sf.ehcache.concurrent.LockType;
19  import net.sf.ehcache.config.CacheConfiguration;
20  
21  import org.junit.Before;
22  import org.junit.Test;
23  
24  import bitronix.tm.TransactionManagerServices;
25  
26  /***
27   * @author Alex Snaps
28   */
29  public class XATransactionalStoreTest {
30  
31      private TransactionManager transactionManager;
32      private Cache cach1;
33      private Cache cache;
34  
35      @Before
36      public void setup() throws Exception {
37          transactionManager = TransactionManagerServices.getTransactionManager();
38          CacheManager cacheManager = CacheManager.getInstance();
39          cache = cacheManager.getCache("xaCache");
40          if (cache == null) {
41              cache = new Cache(new CacheConfiguration("xaCache", 1000).transactionalMode(CacheConfiguration.TransactionalMode.XA_STRICT));
42              cacheManager.addCache(cache);
43          }
44          cach1 = cacheManager.getCache("otherXaCache");
45          if (cach1 == null) {
46              cach1 = new Cache(new CacheConfiguration("otherXaCache", 1000).transactionalMode(CacheConfiguration.TransactionalMode.XA_STRICT));
47              cacheManager.addCache(cach1);
48          }
49          transactionManager.begin();
50          cache.removeAll();
51          cach1.removeAll();
52          transactionManager.commit();
53      }
54  
55      @Test
56      public void testPutIfAbsent() throws Exception {
57          transactionManager.begin();
58          assertEquals("Cache should be empty to start", 0, cache.getSize());
59          assertEquals("Cach1 should be empty to start", 0, cach1.getSize());
60          assertNull(cach1.putIfAbsent(new Element("key", "value1")));
61          assertNull(cache.putIfAbsent(new Element("key", "value1")));
62          Transaction tx1 = transactionManager.suspend();
63          transactionManager.begin();
64          assertNull(cache.putIfAbsent(new Element("key", "value2")));
65          transactionManager.commit();
66          transactionManager.resume(tx1);
67          try {
68              transactionManager.commit();
69              fail("This should have thrown an Exception, as the putIfAbsent should have failed!");
70          } catch (RollbackException e) {
71              // Expected
72          }
73  
74          CacheLockProvider clp = (CacheLockProvider) cache.getInternalContext();
75          assertFalse(clp.getSyncForKey("key").isHeldByCurrentThread(LockType.WRITE));
76  
77          transactionManager.begin();
78          Element element = cache.get("key");
79          assertEquals("value2", element.getValue());
80          assertNull(cach1.get("key"));
81          assertEquals(element, cache.putIfAbsent(new Element("key", "value3")));
82          transactionManager.commit();
83  
84          transactionManager.begin();
85          element = cache.get("key");
86          assertEquals("value2", element.getValue());
87          transactionManager.commit();
88  
89          transactionManager.begin();
90          cache.put(new Element("key2", "randomValue"));
91          cache.putIfAbsent(new Element("key2", "notThere!"));
92          assertEquals("randomValue", cache.get("key2").getValue());
93          transactionManager.commit();
94  
95          transactionManager.begin();
96          assertEquals("randomValue", cache.get("key2").getValue());
97          transactionManager.commit();
98  
99          transactionManager.begin();
100         cach1.remove("key2");
101         cache.remove("key2");
102         cache.putIfAbsent(new Element("key2", "nowThere!"));
103         assertEquals("nowThere!", cache.get("key2").getValue());
104         transactionManager.commit();
105 
106         transactionManager.begin();
107         assertEquals("nowThere!", cache.get("key2").getValue());
108         transactionManager.commit();
109 
110         transactionManager.begin();
111         cache.remove("key2");
112         cache.putIfAbsent(new Element("key2", "nowThere!"));
113         assertEquals("nowThere!", cache.get("key2").getValue());
114         Transaction tx2 = transactionManager.suspend();
115 
116         transactionManager.begin();
117         assertEquals("nowThere!", cache.get("key2").getValue());
118         cache.put(new Element("key2", "newValue"));
119         transactionManager.commit();
120 
121         transactionManager.resume(tx2);
122         cach1.put(new Element("fake", "entry"));
123         try {
124             transactionManager.commit();
125             fail("This should have thrown an Exception!");
126         } catch (RollbackException e) {
127             // Expected
128         }
129 
130         transactionManager.begin();
131         assertEquals("newValue", cache.get("key2").getValue());
132         transactionManager.commit();
133     }
134 
135     @Test
136     public void testRemoveElement() throws Exception {
137         transactionManager.begin();
138         assertEquals("Cache should be empty to start", 0, cache.getSize());
139         assertEquals("Cach1 should be empty to start", 0, cach1.getSize());
140         assertFalse(cache.removeElement(new Element("blah", "someValue")));
141         cache.put(new Element("blah", "value"));
142         assertFalse(cache.removeElement(new Element("blah", "someValue")));
143         transactionManager.commit();
144         transactionManager.begin();
145         assertNotNull(cache.get("blah"));
146         assertTrue(cache.removeElement(new Element("blah", "value")));
147         transactionManager.commit();
148         transactionManager.begin();
149         assertNull(cache.get("blah"));
150         transactionManager.commit();
151 
152         transactionManager.begin();
153         cache.put(new Element("key", "value"));
154         transactionManager.commit();
155         transactionManager.begin();
156         cach1.put(new Element("random", "things"));
157         cache.removeElement(new Element("key", "value"));
158         Transaction tx1 = transactionManager.suspend();
159         transactionManager.begin();
160         assertTrue(cache.removeElement(new Element("key", "value")));
161         transactionManager.commit();
162         transactionManager.resume(tx1);
163         try {
164             transactionManager.commit();
165             fail("Transaction should have failed, element is deleted already");
166         } catch (RollbackException e) {
167             // Expected
168         }
169         transactionManager.begin();
170         assertNull(cache.get("key"));
171         transactionManager.commit();
172 
173         transactionManager.begin();
174         cache.put(new Element("key", "value"));
175         transactionManager.commit();
176         transactionManager.begin();
177         cach1.put(new Element("random", "things"));
178         cache.removeElement(new Element("key", "value"));
179         tx1 = transactionManager.suspend();
180         transactionManager.begin();
181         cache.put(new Element("key", "newValue"));
182         transactionManager.commit();
183         transactionManager.resume(tx1);
184         try {
185             transactionManager.commit();
186             fail("Transaction should have failed, element has changed in the meantime!");
187         } catch (RollbackException e) {
188             // Expected
189         }
190         transactionManager.begin();
191         assertNotNull(cache.get("key"));
192         assertEquals("newValue", cache.get("key").getValue());
193         transactionManager.commit();
194     }
195 
196     @Test
197     public void testReplace() throws Exception {
198         transactionManager.begin();
199         assertEquals("Cache should be empty to start", 0, cache.getSize());
200         assertEquals("Cach1 should be empty to start", 0, cach1.getSize());
201         assertNull(cache.replace(new Element("blah", "someValue")));
202         cache.put(new Element("blah", "value"));
203         assertNotNull(cache.replace(new Element("blah", "someValue")));
204         transactionManager.commit();
205         transactionManager.begin();
206         assertNotNull(cache.get("blah"));
207         assertEquals("someValue", cache.get("blah").getValue());
208         transactionManager.commit();
209 
210         transactionManager.begin();
211         cache.put(new Element("key", "value"));
212         transactionManager.commit();
213         transactionManager.begin();
214         cach1.put(new Element("random", "things"));
215         cache.replace(new Element("key", "newValue"));
216         Transaction tx1 = transactionManager.suspend();
217         transactionManager.begin();
218         cache.remove("key");
219         transactionManager.commit();
220         transactionManager.resume(tx1);
221         try {
222             transactionManager.commit();
223             fail("Transaction should have failed, element is deleted already");
224         } catch (RollbackException e) {
225             // Expected
226         }
227         transactionManager.begin();
228         assertNull(cache.get("key"));
229         transactionManager.commit();
230 
231         transactionManager.begin();
232         cache.put(new Element("key", "value"));
233         transactionManager.commit();
234         transactionManager.begin();
235         cach1.put(new Element("random", "things"));
236         cache.replace(new Element("key", "newValue"));
237         tx1 = transactionManager.suspend();
238         transactionManager.begin();
239         cache.put(new Element("key", "allNewValue"));
240         transactionManager.commit();
241         transactionManager.resume(tx1);
242         try {
243             transactionManager.commit();
244             fail("Transaction should have failed, element is deleted already");
245         } catch (RollbackException e) {
246             // Expected
247         }
248         transactionManager.begin();
249         assertNotNull(cache.get("key"));
250         assertNotNull("allNewValue", cache.get("key").getValue());
251         transactionManager.commit();
252 
253         transactionManager.begin();
254         cache.put(new Element("key", "value"));
255         transactionManager.commit();
256         transactionManager.begin();
257         cach1.put(new Element("random", "things"));
258         cache.replace(new Element("key", "newValue"));
259         tx1 = transactionManager.suspend();
260         transactionManager.begin();
261         cache.put(new Element("key", "allNewValue"));
262         transactionManager.commit();
263         transactionManager.resume(tx1);
264         try {
265             transactionManager.commit();
266             fail("Transaction should have failed, element value has changed");
267         } catch (RollbackException e) {
268             // Expected
269         }
270         transactionManager.begin();
271         assertNotNull(cache.get("key"));
272         assertNotNull("allNewValue", cache.get("key").getValue());
273         transactionManager.commit();
274 
275         transactionManager.begin();
276         cache.put(new Element("key", "value"));
277         transactionManager.commit();
278         transactionManager.begin();
279         cach1.put(new Element("random", "things"));
280         cache.replace(new Element("key", "value"));
281         tx1 = transactionManager.suspend();
282         transactionManager.begin();
283         cache.put(new Element("key", "newValue"));
284         transactionManager.commit();
285         transactionManager.resume(tx1);
286         try {
287             transactionManager.commit();
288             fail("Transaction should have failed, element has changed in the meantime!");
289         } catch (RollbackException e) {
290             // Expected
291         }
292         transactionManager.begin();
293         assertNotNull(cache.get("key"));
294         assertEquals("newValue", cache.get("key").getValue());
295         transactionManager.commit();
296     }
297 
298     @Test
299     public void testReplaceElement() throws Exception {
300         transactionManager.begin();
301         assertEquals("Cache should be empty to start", 0, cache.getSize());
302         assertEquals("Cach1 should be empty to start", 0, cach1.getSize());
303         assertFalse(cache.replace(new Element("blah", "someValue"), new Element("blah", "someOtherValue")));
304         cache.put(new Element("blah", "value"));
305         assertTrue(cache.replace(new Element("blah", "value"), new Element("blah", "someValue")));
306         transactionManager.commit();
307         transactionManager.begin();
308         assertNotNull(cache.get("blah"));
309         assertEquals("someValue", cache.get("blah").getValue());
310         transactionManager.commit();
311 
312         transactionManager.begin();
313         assertEquals("someValue", cache.get("blah").getValue());
314         transactionManager.commit();
315 
316         transactionManager.begin();
317         cache.put(new Element("key", "value"));
318         transactionManager.commit();
319         transactionManager.begin();
320         cach1.put(new Element("random", "things"));
321         cache.replace(new Element("key", "value"), new Element("key", "newValue"));
322         Transaction tx1 = transactionManager.suspend();
323         transactionManager.begin();
324         cache.remove("key");
325         transactionManager.commit();
326         transactionManager.resume(tx1);
327         try {
328             transactionManager.commit();
329             fail("Transaction should have failed, element is deleted already");
330         } catch (RollbackException e) {
331             // Expected
332         }
333         transactionManager.begin();
334         assertNull(cache.get("key"));
335         transactionManager.commit();
336 
337         transactionManager.begin();
338         cache.put(new Element("key", "value"));
339         transactionManager.commit();
340         transactionManager.begin();
341         cach1.put(new Element("random", "things"));
342         assertFalse(cache.replace(new Element("key", "wrongValue"), new Element("key", "newValue")));
343         assertTrue(cache.replace(new Element("key", "value"), new Element("key", "newValue")));
344         tx1 = transactionManager.suspend();
345         transactionManager.begin();
346         cache.put(new Element("key", "allNewValue"));
347         transactionManager.commit();
348         transactionManager.resume(tx1);
349         try {
350             transactionManager.commit();
351             fail("Transaction should have failed, element's value has changed");
352         } catch (RollbackException e) {
353             // Expected
354         }
355         transactionManager.begin();
356         assertNotNull(cache.get("key"));
357         assertNotNull("allNewValue", cache.get("key").getValue());
358         transactionManager.commit();
359 
360         transactionManager.begin();
361         cache.put(new Element("key", "value"));
362         transactionManager.commit();
363         transactionManager.begin();
364         cach1.put(new Element("random", "things"));
365         cache.replace(new Element("key", "value"), new Element("key", "newValue"));
366         tx1 = transactionManager.suspend();
367         transactionManager.begin();
368         cache.put(new Element("key", "allNewValue"));
369         transactionManager.commit();
370         transactionManager.resume(tx1);
371         try {
372             transactionManager.commit();
373             fail("Transaction should have failed, element is deleted already");
374         } catch (RollbackException e) {
375             // Expected
376         }
377         transactionManager.begin();
378         assertNotNull(cache.get("key"));
379         assertNotNull("allNewValue", cache.get("key").getValue());
380         transactionManager.commit();
381 
382         transactionManager.begin();
383         cache.put(new Element("key", "value"));
384         transactionManager.commit();
385         transactionManager.begin();
386         cach1.put(new Element("random", "things"));
387         cache.replace(new Element("key", "value"), new Element("key", "wrongValue"));
388         tx1 = transactionManager.suspend();
389         transactionManager.begin();
390         cache.put(new Element("key", "newValue"));
391         transactionManager.commit();
392         transactionManager.resume(tx1);
393         try {
394             transactionManager.commit();
395             fail("Transaction should have failed, element has changed in the meantime!");
396         } catch (RollbackException e) {
397             // Expected
398         }
399         transactionManager.begin();
400         assertNotNull(cache.get("key"));
401         assertEquals("newValue", cache.get("key").getValue());
402         transactionManager.commit();
403     }
404 }