KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > cache > transaction > TransactionTest


1 /*
2  *
3  * JBoss, the OpenSource J2EE webOS
4  *
5  * Distributable under LGPL license.
6  * See terms of license at gnu.org.
7  */

8
9 package org.jboss.cache.transaction;
10
11 import junit.framework.Test;
12 import junit.framework.TestCase;
13 import junit.framework.TestSuite;
14 import org.jboss.cache.CacheException;
15 import org.jboss.cache.CacheImpl;
16 import org.jboss.cache.Fqn;
17 import org.jboss.cache.GlobalTransaction;
18 import org.jboss.cache.Node;
19 import org.jboss.cache.NodeSPI;
20 import org.jboss.cache.lock.IsolationLevel;
21 import org.jboss.cache.lock.NodeLock;
22
23 import javax.naming.Context JavaDoc;
24 import javax.naming.InitialContext JavaDoc;
25 import javax.transaction.HeuristicMixedException JavaDoc;
26 import javax.transaction.HeuristicRollbackException JavaDoc;
27 import javax.transaction.NotSupportedException JavaDoc;
28 import javax.transaction.RollbackException JavaDoc;
29 import javax.transaction.SystemException JavaDoc;
30 import javax.transaction.Transaction JavaDoc;
31 import javax.transaction.UserTransaction JavaDoc;
32 import java.util.HashMap JavaDoc;
33 import java.util.Map JavaDoc;
34 import java.util.Properties JavaDoc;
35 import java.util.Set JavaDoc;
36
37 /**
38  * Tests transactional access to a local CacheImpl.
39  * Note: we use DummpyTranasctionManager to replace jta
40  *
41  * @version $Id: TransactionTest.java,v 1.23 2007/01/04 05:35:41 msurtani Exp $
42  */

43 public class TransactionTest extends TestCase
44 {
45    CacheImpl cache = null;
46    UserTransaction JavaDoc tx = null;
47    Properties JavaDoc p = null;
48    String JavaDoc old_factory = null;
49    final String JavaDoc FACTORY = "org.jboss.cache.transaction.DummyContextFactory";
50    Exception JavaDoc thread_ex;
51
52
53    public TransactionTest(String JavaDoc name)
54    {
55       super(name);
56    }
57
58    public void setUp() throws Exception JavaDoc
59    {
60       super.setUp();
61       old_factory = System.getProperty(Context.INITIAL_CONTEXT_FACTORY);
62       System.setProperty(Context.INITIAL_CONTEXT_FACTORY, FACTORY);
63       DummyTransactionManager.getInstance();
64       if (p == null)
65       {
66          p = new Properties JavaDoc();
67          p.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.cache.transaction.DummyContextFactory");
68       }
69
70       tx = (UserTransaction JavaDoc) new InitialContext JavaDoc(p).lookup("UserTransaction");
71       cache = new CacheImpl();
72       cache.getConfiguration().setClusterName("test");
73       cache.getConfiguration().setInitialStateRetrievalTimeout(10000);
74       cache.getConfiguration().setTransactionManagerLookupClass("org.jboss.cache.DummyTransactionManagerLookup");
75       cache.getConfiguration().setIsolationLevel(IsolationLevel.SERIALIZABLE);
76       cache.create();
77       cache.start();
78       thread_ex = null;
79    }
80
81    public void tearDown() throws Exception JavaDoc
82    {
83       super.tearDown();
84       if (cache != null)
85       {
86          cache.stop();
87          cache = null;
88       }
89
90       // BW. kind of a hack to destroy jndi binding and thread local tx before next run.
91
DummyTransactionManager.destroy();
92       if (old_factory != null)
93       {
94          System.setProperty(Context.INITIAL_CONTEXT_FACTORY, old_factory);
95          old_factory = null;
96       }
97
98       if (tx != null)
99       {
100          try
101          {
102             tx.rollback();
103          }
104          catch (Throwable JavaDoc t)
105          {
106          }
107          tx = null;
108       }
109    }
110
111
112    public void testPutTx() throws Exception JavaDoc
113    {
114       tx.begin();
115       cache.put("/a/b/c", "age", 38);
116       // the tx interceptor should know that we're in the same tx.
117
assertEquals(cache.get("/a/b/c", "age"), 38);
118
119       cache.put("/a/b/c", "age", 39);
120       tx.commit();
121
122       // This test is done outside the TX, it wouldn't work if someone else
123
// modified "age". This works because we're the only TX running.
124
assertEquals(cache.get("/a/b/c", "age"), 39);
125    }
126
127
128    public void testRollbackTx1()
129    {
130       try
131       {
132          tx.begin();
133          cache.put("/a/b/c", "age", 38);
134          cache.put("/a/b/c", "age", 39);
135          tx.rollback();
136
137          // This test is done outside the TX, it wouldn't work if someone else
138
// modified "age". This works because we're the only TX running.
139
assertNull(cache.get("/a/b/c", "age"));
140       }
141       catch (Throwable JavaDoc t)
142       {
143          t.printStackTrace();
144          fail(t.toString());
145       }
146    }
147
148
149    public void testGetAfterRemovalRollback() throws Exception JavaDoc
150    {
151       assertEquals(0, cache.getNumberOfLocksHeld());
152       cache.put("/a/b", null);
153       assertEquals(0, cache.getNumberOfLocksHeld());
154       assertTrue(cache.exists("/a/b"));
155       tx.begin();
156       cache.remove("/a/b");
157       assertFalse(cache.exists("/a/b"));
158       tx.rollback();
159       assertTrue(cache.exists("/a/b"));
160       assertEquals(0, cache.getNumberOfLocksHeld());
161       // new tx in new thread
162
Thread JavaDoc th = new Thread JavaDoc()
163       {
164          public void run()
165          {
166             try
167             {
168                cache.getTransactionManager().begin();
169                assertNotNull(cache.get("/a/b"));
170                cache.getTransactionManager().rollback();
171             }
172             catch (Exception JavaDoc e)
173             {
174                e.printStackTrace();
175                fail("Caught exception");
176             }
177          }
178       };
179
180       th.start();
181       th.join();
182
183       assertEquals(0, cache.getNumberOfLocksHeld());
184    }
185
186    public void testRollbackTx2()
187    {
188       try
189       {
190          tx.begin();
191          cache.put("/a/b/c", "age", 38);
192          cache.remove("/a/b/c", "age");
193          tx.rollback();
194
195          // This test is done outside the TX, it wouldn't work if someone else
196
// modified "age". This works because we're the only TX running.
197
assertNull(cache.get("/a/b/c", "age"));
198       }
199       catch (Throwable JavaDoc t)
200       {
201          t.printStackTrace();
202          fail(t.toString());
203       }
204    }
205
206    public void testRollbackTx2a()
207    {
208       try
209       {
210          System.out.println("locks " + cache.printLockInfo());
211          cache.put("/a/b/c", "age", 38);
212          System.out.println("locks " + cache.printLockInfo());
213          tx.begin();
214          cache.remove("/a/b/c", "age");
215          tx.rollback();
216
217          // This test is done outside the TX, it wouldn't work if someone else
218
// modified "age". This works because we're the only TX running.
219
assertEquals(38, cache.get("/a/b/c", "age"));
220       }
221       catch (Throwable JavaDoc t)
222       {
223          t.printStackTrace();
224          fail(t.toString());
225       }
226    }
227
228    public void testRollbackTx3()
229    {
230       try
231       {
232          java.util.Map JavaDoc map1 = new java.util.HashMap JavaDoc();
233          map1.put("age", 38);
234          java.util.Map JavaDoc map2 = new java.util.HashMap JavaDoc();
235          map2.put("age", 39);
236          tx.begin();
237          cache.put("/a/b/c", map1);
238          cache.put("/a/b/c", map2);
239          tx.rollback();
240
241          // This test is done outside the TX, it wouldn't work if someone else
242
// modified "age". This works because we're the only TX running.
243
assertNull(cache.get("/a/b/c", "age"));
244       }
245       catch (Throwable JavaDoc t)
246       {
247          t.printStackTrace();
248          fail(t.toString());
249       }
250    }
251
252
253    public void testRollbackTx4()
254    {
255       try
256       {
257          Map JavaDoc map = new HashMap JavaDoc();
258          map.put("age", 38);
259          tx.begin();
260          cache.put("/a/b/c", map);
261          cache.remove("/a/b/c");
262          tx.rollback();
263
264          // This test is done outside the TX, it wouldn't work if someone else
265
// modified "age". This works because we're the only TX running.
266
assertNull(cache.get("/a/b/c", "age"));
267       }
268       catch (Throwable JavaDoc t)
269       {
270          t.printStackTrace();
271          fail(t.toString());
272       }
273    }
274
275    public void testNodeCreationRollback()
276    {
277       try
278       {
279          tx.begin();
280          System.out.println("initial state:\n" + cache);
281          cache.put("/bela/ban", "key", "value");
282          System.out.println("after put():\n" + cache);
283          tx.rollback();
284          System.out.println("after rollback():\n" + cache);
285
286          assertNull("node should be not existent", cache.get("/bela/ban"));
287       }
288       catch (Throwable JavaDoc t)
289       {
290          t.printStackTrace();
291          fail(t.toString());
292       }
293    }
294
295    public void testNodeCreationRollback2()
296    {
297       try
298       {
299          cache.put("/bela/ban", null);
300          tx.begin();
301          cache.put("/bela/ban/michelle", null);
302          tx.rollback();
303          assertNotNull("node should be not null", cache.get("/bela/ban"));
304          assertNull("node should be not existent", cache.get("/bela/ban/michelle"));
305       }
306       catch (Throwable JavaDoc t)
307       {
308          t.printStackTrace();
309          fail(t.toString());
310       }
311    }
312
313    public void testNodeDeletionRollback()
314    {
315       try
316       {
317          cache.put("/a/b/c", null);
318          tx.begin();
319          cache.remove("/a/b/c");
320          assertNull(cache.get("/a/b/c"));
321          cache.remove("/a/b");
322          assertNull(cache.get("/a/b"));
323          cache.remove("/a");
324          assertNull(cache.get("/a"));
325          tx.rollback();
326          assertNotNull(cache.get("/a/b/c"));
327          assertNotNull(cache.get("/a/b"));
328          assertNotNull(cache.get("/a"));
329       }
330       catch (Throwable JavaDoc t)
331       {
332          t.printStackTrace();
333          fail(t.toString());
334       }
335    }
336
337    public void testNodeDeletionRollback2() throws Exception JavaDoc
338    {
339       cache.put("/a/b/c", null);
340       cache.put("/a/b/c1", null);
341       cache.put("/a/b/c2", null);
342       tx.begin();
343       cache.remove("/a");
344       assertNull(cache.get("/a/b/c"));
345       assertNull(cache.get("/a/b/c1"));
346       assertNull(cache.get("/a/b/c2"));
347       assertNull(cache.get("/a/b"));
348       assertNull(cache.get("/a"));
349       Set JavaDoc children = cache.getChildrenNames("/a/b");
350       assertTrue(children.isEmpty());
351       children = cache.getChildrenNames("/a");
352       assertTrue(children.isEmpty());
353       tx.rollback();
354       assertNotNull(cache.get("/a"));
355       assertNotNull(cache.get("/a/b"));
356       assertNotNull(cache.get("/a/b/c"));
357       assertNotNull(cache.get("/a/b/c1"));
358       assertNotNull(cache.get("/a/b/c2"));
359       children = cache.getChildrenNames("/a/b");
360       assertEquals(3, children.size());
361    }
362
363
364    public void testNodeCreation() throws Exception JavaDoc
365    {
366       GlobalTransaction gtx;
367       cache.put("/a/b", null);
368       tx.begin();
369       gtx = cache.getCurrentTransaction();
370       cache.put("/a/b/c", null);
371       assertLocked(gtx, "/a", false);
372       assertLocked(gtx, "/a/b", true);
373       assertLocked(gtx, "/a/b/c", true);
374       System.out.println("locks: " + cache.printLockInfo());
375    }
376
377
378    public void testNodeCreation2() throws Exception JavaDoc
379    {
380       GlobalTransaction gtx;
381       tx.begin();
382       gtx = cache.getCurrentTransaction();
383       cache.put("/a/b/c", null);
384       assertLocked(gtx, "/a", true);
385       assertLocked(gtx, "/a/b", true);
386       assertLocked(gtx, "/a/b/c", true);
387       System.out.println("locks: " + cache.printLockInfo());
388    }
389
390
391    public void testNodeRemoval()
392    {
393       GlobalTransaction gtx;
394       try
395       {
396          cache.put("/a/b/c", null);
397          tx.begin();
398          gtx = cache.getCurrentTransaction();
399          cache.remove("/a/b/c");// need to remove the node, not just the data in the node.
400
System.out.println("Locks: " + cache.printLockInfo());
401          assertLocked(gtx, "/a", false);
402          assertLocked(gtx, "/a/b", true);
403          assertLocked(gtx, "/a/b/c", true);
404          System.out.println("locks: " + cache.printLockInfo());
405       }
406       catch (Throwable JavaDoc t)
407       {
408          t.printStackTrace();
409          fail(t.toString());
410       }
411    }
412
413
414    public void testNodeRemoval2()
415    {
416       GlobalTransaction gtx;
417       try
418       {
419          cache.put("/a/b/c", null);
420          tx.begin();
421          gtx = cache.getCurrentTransaction();
422          cache.remove("/a/b");// need to remove the node, not just the data in the node.
423
assertLocked(gtx, "/a", true);
424          assertLocked(gtx, "/a/b", true);
425          assertLocked(gtx, "/a/b/c", true);
426          System.out.println("locks: " + cache.printLockInfo());
427       }
428       catch (Throwable JavaDoc t)
429       {
430          t.printStackTrace();
431          fail(t.toString());
432       }
433    }
434
435    public void testIntermediateNodeCreationOnWrite() throws Exception JavaDoc
436    {
437       cache.put("/a", null);
438       tx.begin();
439       cache.put("/a/b/c", null);
440       // expecting WLs on /a, /a/b and /a/b/c.
441
GlobalTransaction gtx = cache.getCurrentTransaction();
442       assertLocked(gtx, "/a", true);
443       assertLocked(gtx, "/a/b", true);
444       assertLocked(gtx, "/a/b/c", true);
445       tx.rollback();
446
447    }
448
449    public void testIntermediateNodeCreationOnRead() throws Exception JavaDoc
450    {
451       cache.put("/a", null);
452       tx.begin();
453       cache.get("/a/b/c");
454
455       // expecting RLs on /, /a
456
// /a/b, /a/b/c should NOT be created!
457
GlobalTransaction gtx = cache.getCurrentTransaction();
458       assertLocked(gtx, "/", false);
459       assertLocked(gtx, "/a", false);
460       assertNull("/a/b should not exist", cache.peek(Fqn.fromString("/a/b")));
461       assertNull("/a/b/c should not exist", cache.peek(Fqn.fromString("/a/b/c")));
462       tx.rollback();
463       assertNull("/a/b should not exist", cache.peek(Fqn.fromString("/a/b")));
464       assertNull("/a/b/c should not exist", cache.peek(Fqn.fromString("/a/b/c")));
465
466    }
467
468
469    public void testIntermediateNodeCreationOnRemove() throws Exception JavaDoc
470    {
471       cache.put("/a", null);
472       tx.begin();
473       cache.remove("/a/b/c");
474
475       // expecting RLs on /, /a
476
// /a/b, /a/b/c should NOT be created!
477
GlobalTransaction gtx = cache.getCurrentTransaction();
478       assertLocked(gtx, "/", false);
479       assertLocked(gtx, "/a", false);
480       assertNull("/a/b should not exist", cache.peek(Fqn.fromString("/a/b")));
481       assertNull("/a/b/c should not exist", cache.peek(Fqn.fromString("/a/b/c")));
482       tx.rollback();
483       assertNull("/a/b should not exist", cache.peek(Fqn.fromString("/a/b")));
484       assertNull("/a/b/c should not exist", cache.peek(Fqn.fromString("/a/b/c")));
485
486    }
487
488
489    public void testNodeDeletionRollback3() throws Exception JavaDoc
490    {
491       GlobalTransaction gtx;
492       cache.put("/a/b/c1", null);
493
494       tx.begin();
495       gtx = cache.getCurrentTransaction();
496       cache.put("/a/b/c1", null);
497       assertLocked(gtx, "/a", false);
498       assertLocked(gtx, "/a/b", false);
499       assertLocked(gtx, "/a/b/c1", true);
500
501       cache.put("/a/b/c2", null);
502       assertLocked(gtx, "/a/b", true);
503       assertLocked(gtx, "/a/b/c2", true);
504
505       cache.put("/a/b/c3", null);
506       cache.put("/a/b/c1/one", null);
507       assertLocked(gtx, "/a/b/c1", true);
508       assertLocked(gtx, "/a/b/c1/one", true);
509
510       cache.put("/a/b/c1/two", null);
511       cache.put("/a/b/c1/one/1", null);
512       assertLocked(gtx, "/a/b/c1", true);
513       assertLocked(gtx, "/a/b/c1/one", true);
514       assertLocked(gtx, "/a/b/c1/one/1", true);
515
516       cache.put("/a/b/c1/two/2/3/4", null);
517       assertLocked(gtx, "/a/b/c1", true);
518       assertLocked(gtx, "/a/b/c1/two", true);
519       assertLocked(gtx, "/a/b/c1/two/2", true);
520       assertLocked(gtx, "/a/b/c1/two/2/3", true);
521       assertLocked(gtx, "/a/b/c1/two/2/3/4", true);
522
523       System.out.println("locks: " + cache.printLockInfo());
524
525       cache.remove("/a/b");
526       tx.rollback();
527       assertTrue(cache.getChildrenNames("/a/b/c1").isEmpty());
528       Set JavaDoc cn = cache.getChildrenNames("/a/b");
529       assertEquals(1, cn.size());
530       assertEquals("c1", cn.iterator().next());
531    }
532
533    public void testDoubleLocks() throws Exception JavaDoc
534    {
535       tx.begin();
536       GlobalTransaction gtx = cache.getCurrentTransaction();
537       cache.put("/a/b/c", null);
538       cache.put("/a/b/c", null);
539
540       NodeSPI n = (NodeSPI) cache.get("/a");
541       NodeLock lock = n.getLock();
542       int num = lock.getReaderOwners().size();
543       assertEquals(0, num);
544       // make sure this is write locked.
545
assertLocked(gtx, "/a", true);
546
547       n = (NodeSPI) cache.get("/a/b");
548       lock = n.getLock();
549       num = lock.getReaderOwners().size();
550       assertEquals(0, num);
551       // make sure this is write locked.
552
assertLocked(gtx, "/a/b", true);
553
554       n = (NodeSPI) cache.get("/a/b/c");
555       lock = n.getLock();
556       num = lock.getReaderOwners().size();
557       assertEquals(0, num);
558       // make sure this is write locked.
559
assertLocked(gtx, "/a/b/c", true);
560
561       tx.rollback();
562       assertEquals(0, cache.getNumberOfLocksHeld());
563    }
564
565    private void assertLocked(Object JavaDoc owner, String JavaDoc fqn, boolean write_locked) throws Exception JavaDoc
566    {
567       NodeSPI n = cache.peek(Fqn.fromString(fqn));
568       NodeLock lock = n.getLock();
569       if (owner == null)
570       {
571          owner = Thread.currentThread();
572       }
573       assertTrue("node " + fqn + " is not locked", lock.isLocked());
574       if (write_locked)
575       {
576          assertTrue("node " + fqn + " is not write-locked" + (lock.isReadLocked() ? " but is read-locked instead!" : "!"), lock.isWriteLocked());
577       }
578       else
579       {
580          assertTrue("node " + fqn + " is not read-locked" + (lock.isWriteLocked() ? " but is write-locked instead!" : "!"), lock.isReadLocked());
581       }
582       assertTrue("owner " + owner + "is not owner", lock.isOwner(owner));
583    }
584
585    public void testConcurrentNodeAccessOnRemovalWithTx() throws Exception JavaDoc
586    {
587       cache.put("/a/b/c", null);
588       tx.begin();
589       cache.remove("/a/b/c");
590       // this node should now be locked.
591
Transaction t = cache.getTransactionManager().suspend();
592       Transaction t2 = null;
593       try
594       {
595          System.out.println(cache.printLockInfo());
596          // start a new tx
597
cache.getTransactionManager().begin();
598          t2 = cache.getTransactionManager().getTransaction();
599          cache.get("/a/b/c");// should fail
600
t2.commit();
601          fail("Should not be able to get a hold of /a/b/c until the deleting tx completes");
602       }
603       catch (Exception JavaDoc e)
604       {
605          // expected
606
t2.commit();
607       }
608
609       cache.getTransactionManager().resume(t);
610       tx.rollback();
611
612       assertNotNull(cache.get("/a/b/c"));
613       assertEquals(0, cache.getNumberOfLocksHeld());
614    }
615
616    public void testConcurrentNodeAccessOnRemovalWithoutTx() throws Exception JavaDoc
617    {
618       cache.put("/a/b/c", null);
619       tx.begin();
620       cache.remove("/a/b/c");
621       // this node should now be locked.
622
Transaction t = cache.getTransactionManager().suspend();
623       Thread JavaDoc th = new Thread JavaDoc()
624       {
625          public void run()
626          {
627             try
628             {
629                System.out.println(cache.printLockInfo());
630                cache.get("/a/b/c");// should fail
631

632                fail("Should not be able to get a hold of /a/b/c until the deleting tx completes");
633             }
634             catch (Exception JavaDoc e)
635             {
636                // expected
637
}
638          }
639       };
640
641       th.start();
642       th.join();
643
644       cache.getTransactionManager().resume(t);
645       tx.rollback();
646
647       assertNotNull(cache.get("/a/b/c"));
648       assertEquals(0, cache.getNumberOfLocksHeld());
649    }
650
651
652    public void testRemove() throws CacheException, SystemException JavaDoc, NotSupportedException JavaDoc, HeuristicMixedException JavaDoc, HeuristicRollbackException JavaDoc, RollbackException JavaDoc
653    {
654       cache.put("/a/b/c", null);
655       cache.put("/a/b/c/1", null);
656       cache.put("/a/b/c/2", null);
657       cache.put("/a/b/c/3", null);
658       cache.put("/a/b/c/3/a/b/c", null);
659
660       assertEquals(0, cache.getNumberOfLocksHeld());
661       assertEquals(0, cache.getLockTable().size());
662
663       tx.begin();
664       cache.remove("/a/b/c");
665       System.out.println("locks held (after removing /a/b/c): \n" + cache.printLockInfo());
666       // this used to test for 2 locks held. After the fixes for JBCACHE-875 however, 2 more locks are acquired - for the root node as well as the deleted node.
667
// and since we would lock all children of the deleted node as well, we have 10 locks here.
668
assertEquals(10, cache.getNumberOfLocksHeld());
669       tx.commit();
670       System.out.println("locks held (after committing /a/b/c): \n" + cache.printLockInfo());
671       assertEquals(0, cache.getNumberOfLocksHeld());
672    }
673
674
675    public void testRemoveAndRollback() throws CacheException, SystemException JavaDoc, NotSupportedException JavaDoc, HeuristicMixedException JavaDoc, HeuristicRollbackException JavaDoc, RollbackException JavaDoc
676    {
677       cache.put("/a/b/c", null);
678       cache.put("/a/b/c/1", null);
679       cache.put("/a/b/c/2", null);
680       cache.put("/a/b/c/3", null);
681       cache.put("/a/b/c/3/a/b/c", null);
682
683       assertEquals(0, cache.getNumberOfLocksHeld());
684       assertEquals(0, cache.getLockTable().size());
685
686       tx.begin();
687       System.out.println("locks held (before removing /a/b/c): \n" + cache.printLockInfo());
688       cache.remove("/a/b/c");
689       System.out.println("locks held (after removing /a/b/c): \n" + cache.printLockInfo());
690       assertEquals(10, cache.getNumberOfLocksHeld());
691       tx.rollback();
692       System.out.println("locks held (after rollback): \n" + cache.printLockInfo());
693       assertEquals(0, cache.getNumberOfLocksHeld());
694
695       assertTrue(cache.exists("/a/b/c"));
696       assertTrue(cache.exists("/a/b/c/1"));
697       assertTrue(cache.exists("/a/b/c/2"));
698       assertTrue(cache.exists("/a/b/c/3"));
699       assertTrue(cache.exists("/a/b/c/3/a"));
700       assertTrue(cache.exists("/a/b/c/3/a/b"));
701       assertTrue(cache.exists("/a/b/c/3/a/b/c"));
702    }
703
704
705    public void testRemoveKeyRollback() throws CacheException, SystemException JavaDoc, NotSupportedException JavaDoc
706    {
707       cache.put("/bela/ban", "name", "Bela");
708       tx.begin();
709       cache.remove("/bela/ban", "name");
710       assertNull(cache.get("/bela/ban", "name"));
711       tx.rollback();
712       assertEquals("Bela", cache.get("/bela/ban", "name"));
713    }
714
715
716    public void testRemoveKeyRollback2()
717    {
718       try
719       {
720          Map JavaDoc m = new HashMap JavaDoc();
721          m.put("name", "Bela");
722          m.put("id", 322649);
723          cache.put("/bela/ban", m);
724          tx.begin();
725          cache.remove("/bela/ban", "name");
726          assertNull(cache.get("/bela/ban", "name"));
727          tx.rollback();
728          assertEquals("Bela", cache.get("/bela/ban", "name"));
729       }
730       catch (Throwable JavaDoc t)
731       {
732          t.printStackTrace();
733          fail(t.toString());
734       }
735    }
736
737    public void testRemoveKeyRollback3()
738    {
739       try
740       {
741          cache.put("/bela/ban", "name", "Bela");
742          tx.begin();
743          cache.put("/bela/ban", "name", "Michelle");
744          cache.remove("/bela/ban", "name");
745          assertNull(cache.get("/bela/ban", "name"));
746          tx.rollback();
747          assertEquals("Bela", cache.get("/bela/ban", "name"));
748       }
749       catch (Throwable JavaDoc t)
750       {
751          t.printStackTrace();
752          fail(t.toString());
753       }
754    }
755
756
757    public void testDoubleRemovalOfSameData()
758    {
759       try
760       {
761          tx.begin();
762          cache.put("/foo/1", "item", 1);
763          assertEquals(cache.get("/foo/1", "item"), 1);
764          cache.remove("/foo/1");
765          assertNull(cache.get("/foo/1", "item"));
766          cache.remove("/foo/1");
767          assertNull(cache.get("/foo/1", "item"));
768          tx.rollback();
769          assertFalse(cache.exists("/foo/1"));
770          assertNull(cache.get("/foo/1", "item"));
771       }
772       catch (Throwable JavaDoc t)
773       {
774          t.printStackTrace();
775          fail(t.toString());
776       }
777    }
778
779    /**
780     * put(Fqn, Map) with a previous null map
781     */

782    public void testPutDataRollback1()
783    {
784       try
785       {
786          cache.put("/bela/ban", null);// create a node /bela/ban with a null map
787
tx.begin();
788          Map JavaDoc m = new HashMap JavaDoc();
789          m.put("name", "Bela");
790          m.put("id", 322649);
791          cache.put("/bela/ban", m);
792          tx.rollback();
793
794          Node n = cache.get("/bela/ban");
795          if (n.getData() == null) return;
796          assertEquals("map should be empty", 0, n.getData().size());
797       }
798       catch (Throwable JavaDoc t)
799       {
800          t.printStackTrace();
801          fail(t.toString());
802       }
803    }
804
805    /**
806     * put(Fqn, Map) with a previous non-null map
807     */

808    public void testputDataRollback2()
809    {
810       Map JavaDoc m1, m2;
811       m1 = new HashMap JavaDoc();
812       m1.put("name", "Bela");
813       m1.put("id", 322649);
814       m2 = new HashMap JavaDoc();
815       m2.put("other", "bla");
816       m2.put("name", "Michelle");
817
818       try
819       {
820          cache.put("/bela/ban", m1);
821          tx.begin();
822
823          cache.put("/bela/ban", m2);
824          Map JavaDoc tmp = cache.get("/bela/ban").getData();
825          assertEquals(3, tmp.size());
826          assertEquals("Michelle", tmp.get("name"));
827          assertEquals(tmp.get("id"), 322649);
828          assertEquals("bla", tmp.get("other"));
829          tx.rollback();
830
831          tmp = cache.get("/bela/ban").getData();
832          assertEquals(2, tmp.size());
833          assertEquals("Bela", tmp.get("name"));
834          assertEquals(tmp.get("id"), 322649);
835       }
836       catch (Throwable JavaDoc t)
837       {
838          t.printStackTrace();
839          fail(t.toString());
840       }
841    }
842
843
844    public void testPutRollback()
845    {
846       try
847       {
848          cache.put("/bela/ban", null);// /bela/ban needs to exist
849
tx.begin();
850          cache.put("/bela/ban", "name", "Bela");
851          assertEquals("Bela", cache.get("/bela/ban", "name"));
852          tx.rollback();
853          assertNull(cache.get("/bela/ban", "name"));
854       }
855       catch (Throwable JavaDoc t)
856       {
857          t.printStackTrace();
858          fail(t.toString());
859       }
860    }
861
862
863    public void testPutRollback2()
864    {
865       try
866       {
867          cache.put("/bela/ban", "name", "Bela");// /bela/ban needs to exist
868
tx.begin();
869          cache.put("/bela/ban", "name", "Michelle");
870          assertEquals("Michelle", cache.get("/bela/ban", "name"));
871          tx.rollback();
872          assertEquals("Bela", cache.get("/bela/ban", "name"));
873       }
874       catch (Throwable JavaDoc t)
875       {
876          t.printStackTrace();
877          fail(t.toString());
878       }
879    }
880
881
882    public void testSimpleRollbackTransactions() throws Exception JavaDoc
883    {
884       final Fqn FQN = Fqn.fromString("/a/b/c");
885       tx.begin();
886       cache.put(FQN, "entry", "commit");
887       tx.commit();
888
889       tx.begin();
890       cache.put(FQN, "entry", "rollback");
891       cache.remove(FQN);
892       tx.rollback();
893       assertEquals("Node should keep the commited value", "commit", cache.get(FQN).get("entry"));
894
895       tx.begin();
896       cache.remove(FQN);
897       cache.put(FQN, "entry", "rollback");
898       tx.rollback();
899       assertEquals("Node should keep the commited value", "commit", cache.get(FQN).get("entry"));// THIS FAILS
900
}
901
902
903    private Transaction startTransaction() throws Exception JavaDoc
904    {
905       DummyTransactionManager mgr = DummyTransactionManager.getInstance();
906       mgr.begin();
907       return mgr.getTransaction();
908    }
909
910
911    public void testConcurrentReadAndWriteAccess() throws Exception JavaDoc
912    {
913       cache.stop();
914       cache.getConfiguration().setIsolationLevel(IsolationLevel.REPEATABLE_READ);
915       cache.start();
916
917       cache.put("/1/2/3/4", "foo", "bar");// no TX, no locks held after put() returns
918

919
920       class Reader extends Thread JavaDoc
921       {
922          Transaction thread_tx;
923
924          public Reader()
925          {
926             super("Reader");
927          }
928
929          public void run()
930          {
931             try
932             {
933                thread_tx = startTransaction();
934                log("acquiring RL");
935                cache.get("/1/2/3", "foo");// acquires RLs on all 3 nodes
936
log("RL acquired successfully");
937                sleep(2000);
938                log("committing TX");
939                thread_tx.commit();// releases RLs
940
log("committed TX");
941             }
942             catch (Exception JavaDoc e)
943             {
944                thread_ex = e;
945             }
946          }
947       }
948
949       class Writer extends Thread JavaDoc
950       {
951          Transaction thread_tx;
952
953          public Writer()
954          {
955             super("Writer");
956          }
957
958          public void run()
959          {
960             try
961             {
962                sleep(500);// give the Reader a chance to acquire the RLs
963
thread_tx = startTransaction();
964                log("acquiring WL");
965                cache.put("/1", "foo", "bar2");// needs to acquired a WL on /1
966
log("acquired WL successfully");
967                log("committing TX");
968                thread_tx.commit();
969                log("committed TX");
970             }
971             catch (Exception JavaDoc e)
972             {
973                thread_ex = e;
974             }
975          }
976       }
977
978       Reader reader = new Reader();
979       Writer writer = new Writer();
980       reader.start();
981       writer.start();
982       reader.join();
983       writer.join();
984       if (thread_ex != null)
985       {
986          throw thread_ex;
987       }
988    }
989
990
991    /* public void testConcurrentReadAccess() throws Exception {
992          cache.setIsolationLevel(IsolationLevel.REPEATABLE_READ);
993          cache.setUseMbean(false);
994
995          cache.put("/1/2/3/4", "foo", "bar"); // no TX, no locks held after put() returns
996
997
998          class Reader extends Thread {
999             Transaction thread_tx;
1000
1001            public Reader(String name) {
1002               super(name);
1003            }
1004
1005            public void run() {
1006               try {
1007                  thread_tx=startTransaction();
1008                  log("acquiring RL");
1009                  cache.get("/1/2/3", "foo"); // acquires RLs on all 3 nodes
1010                  log("RL acquired successfully");
1011                  sleep(200000);
1012                  log("committing TX");
1013                  thread_tx.commit(); // releases RLs
1014                  log("committed TX");
1015               }
1016               catch(Exception e) {
1017                  thread_ex=e;
1018               }
1019            }
1020         }
1021
1022
1023         Reader reader=new Reader("R1");
1024         Reader reader2=new Reader("R2");
1025         reader.start();
1026         reader2.start();
1027         reader.join();
1028         reader2.join();
1029         if(thread_ex != null)
1030            throw thread_ex;
1031      }
1032
1033   */

1034   private static void log(String JavaDoc msg)
1035   {
1036      System.out.println(Thread.currentThread().getName() + ": " + msg);
1037   }
1038
1039   // public void testRaceConditionOnNotInCacheCondition() throws Exception {
1040
// cache.setIsolationLevel(IsolationLevel.SERIALIZABLE);
1041
//
1042
// tx.begin();
1043
// // we now read the null entry, and decide that we need to go do something.
1044
//
1045
// Object cachedObject=cache.get("/SecurityInfo/", Integer.toString(23));
1046
// assertNull(cachedObject); // we expect this in this test
1047
//
1048
// /**
1049
// * now start another Thread to go do the same action, looking for the value, but it SHOULD
1050
// * see the result of the main thread put once it commits.
1051
// */
1052
// Thread thread=new Thread(new Runnable() {
1053
// UserTransaction tx2=(UserTransaction)new InitialContext(p).lookup("UserTransaction");
1054
// public void run() {
1055
// try {
1056
// tx2.begin();
1057
// log("OtherThread: inspecting the cache");
1058
// Object cachedObject=cache.get("/SecurityInfo", Integer.toString(23));
1059
//
1060
// log("OtherThread: read from cache: " + cachedObject);
1061
// Thread.sleep(3000);
1062
//
1063
// cachedObject=cache.get("/SecurityInfo", Integer.toString(23));
1064
// log("OtherThread: read(second time) from cache:" + cachedObject);
1065
//
1066
// /**
1067
// * This should really fail because the other thread should actually have put something else there.
1068
// */
1069
// cache.put("/SecurityInfo", Integer.toString(23), "HelloWorldDIRTY!");
1070
//
1071
// log("OtherThread: Has put something in the cache tha shouldn't be there");
1072
// }
1073
// catch(Exception e) {
1074
// e.printStackTrace();
1075
// }
1076
// finally {
1077
// if(tx2 != null)
1078
// try {tx2.commit();} catch(Exception e) {e.printStackTrace();}
1079
// }
1080
// log("OthreThread: exiting");
1081
//
1082
// }
1083
// });
1084
//
1085
// thread.start();
1086
// log("MainThread is now waiting a little bit");
1087
// Thread.sleep(2000); // wait long enough for the other thread to block a bit. Simulate a DB read
1088
// log("MainThread is now putting something in the cache");
1089
// cache.put("/SecurityInfo", Integer.toString(23), "HelloWorld");
1090
// Thread.sleep(2000); // wait long enough for the other thread to block a bit. Simulate a DB read
1091
// tx.commit();
1092
// log("MainThread: committed");
1093
// thread.join(30000);
1094
//
1095
// log(cache.get("/SecurityInfo", Integer.toString(23)).toString());
1096
// }
1097

1098   // public void testConcurrentReadsWithSerializableIsolationLevel() throws CacheException, InterruptedException {
1099
// final long TIMEOUT=5000;
1100
// cache.setIsolationLevel(IsolationLevel.SERIALIZABLE);
1101
// cache.put("/testfqn", "testkey", "testvalue"); // add initial value, to be read by threads
1102
// Reader r1, r2;
1103
// r1=new Reader("reader1", 3000);
1104
// r2=new Reader("reader2", 0);
1105
// r1.start();
1106
// pause(100); // make sure thread1 starts and acquires the lock before thread2
1107
// r2.start();
1108
// r1.join(TIMEOUT);
1109
// r2.join(TIMEOUT);
1110
// }
1111
//
1112
// class Reader extends Thread {
1113
// long timeout;
1114
//
1115
// public Reader(String name, long timeout) {
1116
// super(name);
1117
// this.timeout=timeout;
1118
// }
1119
//
1120
// public void run() {
1121
// UserTransaction trans=null;
1122
// try {
1123
// trans=(UserTransaction)new InitialContext(p).lookup("UserTransaction");
1124
// trans.begin();
1125
// Object retval=null;
1126
// log2("accessing tree");
1127
// retval=cache.get("testfqn", "testkey");
1128
// log2("retval: " + retval);
1129
// if(timeout > 0) {
1130
// log2("sleeping for " + timeout + " ms");
1131
// pause(timeout);
1132
// }
1133
// }
1134
// catch(Exception e) {
1135
// e.printStackTrace();
1136
// }
1137
// finally {
1138
// try {trans.commit();} catch(Throwable t) {}
1139
// log2("done");
1140
// }
1141
// }
1142
// }
1143

1144   // private void pause(long timeout) {
1145
// try {
1146
// Thread.sleep(timeout);
1147
// }
1148
// catch(InterruptedException e) {
1149
// }
1150
// }
1151
//
1152
// private void log(String msg) {
1153
// System.out.println("-- [" + Thread.currentThread() + "]: " + msg);
1154
// }
1155
//
1156
// private void log2(String msg) {
1157
// System.out.println("-- [" + System.currentTimeMillis() + " " + Thread.currentThread() + "]: " + msg);
1158
// }
1159

1160
1161   public static Test suite() throws Exception JavaDoc
1162   {
1163      return new TestSuite(TransactionTest.class);
1164   }
1165
1166   public static void main(String JavaDoc[] args) throws Exception JavaDoc
1167   {
1168      junit.textui.TestRunner.run(suite());
1169   }
1170
1171
1172}
1173
Popular Tags