1 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 ; 24 import javax.naming.InitialContext ; 25 import javax.transaction.HeuristicMixedException ; 26 import javax.transaction.HeuristicRollbackException ; 27 import javax.transaction.NotSupportedException ; 28 import javax.transaction.RollbackException ; 29 import javax.transaction.SystemException ; 30 import javax.transaction.Transaction ; 31 import javax.transaction.UserTransaction ; 32 import java.util.HashMap ; 33 import java.util.Map ; 34 import java.util.Properties ; 35 import java.util.Set ; 36 37 43 public class TransactionTest extends TestCase 44 { 45 CacheImpl cache = null; 46 UserTransaction tx = null; 47 Properties p = null; 48 String old_factory = null; 49 final String FACTORY = "org.jboss.cache.transaction.DummyContextFactory"; 50 Exception thread_ex; 51 52 53 public TransactionTest(String name) 54 { 55 super(name); 56 } 57 58 public void setUp() throws Exception 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 (); 67 p.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.cache.transaction.DummyContextFactory"); 68 } 69 70 tx = (UserTransaction ) new InitialContext (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 82 { 83 super.tearDown(); 84 if (cache != null) 85 { 86 cache.stop(); 87 cache = null; 88 } 89 90 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 t) 105 { 106 } 107 tx = null; 108 } 109 } 110 111 112 public void testPutTx() throws Exception 113 { 114 tx.begin(); 115 cache.put("/a/b/c", "age", 38); 116 assertEquals(cache.get("/a/b/c", "age"), 38); 118 119 cache.put("/a/b/c", "age", 39); 120 tx.commit(); 121 122 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 assertNull(cache.get("/a/b/c", "age")); 140 } 141 catch (Throwable t) 142 { 143 t.printStackTrace(); 144 fail(t.toString()); 145 } 146 } 147 148 149 public void testGetAfterRemovalRollback() throws Exception 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 Thread th = new Thread () 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 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 assertNull(cache.get("/a/b/c", "age")); 198 } 199 catch (Throwable 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 assertEquals(38, cache.get("/a/b/c", "age")); 220 } 221 catch (Throwable t) 222 { 223 t.printStackTrace(); 224 fail(t.toString()); 225 } 226 } 227 228 public void testRollbackTx3() 229 { 230 try 231 { 232 java.util.Map map1 = new java.util.HashMap (); 233 map1.put("age", 38); 234 java.util.Map map2 = new java.util.HashMap (); 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 assertNull(cache.get("/a/b/c", "age")); 244 } 245 catch (Throwable t) 246 { 247 t.printStackTrace(); 248 fail(t.toString()); 249 } 250 } 251 252 253 public void testRollbackTx4() 254 { 255 try 256 { 257 Map map = new HashMap (); 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 assertNull(cache.get("/a/b/c", "age")); 267 } 268 catch (Throwable 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 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 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 t) 331 { 332 t.printStackTrace(); 333 fail(t.toString()); 334 } 335 } 336 337 public void testNodeDeletionRollback2() throws Exception 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 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 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 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"); 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 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"); 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 t) 429 { 430 t.printStackTrace(); 431 fail(t.toString()); 432 } 433 } 434 435 public void testIntermediateNodeCreationOnWrite() throws Exception 436 { 437 cache.put("/a", null); 438 tx.begin(); 439 cache.put("/a/b/c", null); 440 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 450 { 451 cache.put("/a", null); 452 tx.begin(); 453 cache.get("/a/b/c"); 454 455 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 470 { 471 cache.put("/a", null); 472 tx.begin(); 473 cache.remove("/a/b/c"); 474 475 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 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 cn = cache.getChildrenNames("/a/b"); 529 assertEquals(1, cn.size()); 530 assertEquals("c1", cn.iterator().next()); 531 } 532 533 public void testDoubleLocks() throws Exception 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 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 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 assertLocked(gtx, "/a/b/c", true); 560 561 tx.rollback(); 562 assertEquals(0, cache.getNumberOfLocksHeld()); 563 } 564 565 private void assertLocked(Object owner, String fqn, boolean write_locked) throws Exception 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 586 { 587 cache.put("/a/b/c", null); 588 tx.begin(); 589 cache.remove("/a/b/c"); 590 Transaction t = cache.getTransactionManager().suspend(); 592 Transaction t2 = null; 593 try 594 { 595 System.out.println(cache.printLockInfo()); 596 cache.getTransactionManager().begin(); 598 t2 = cache.getTransactionManager().getTransaction(); 599 cache.get("/a/b/c"); 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 e) 604 { 605 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 617 { 618 cache.put("/a/b/c", null); 619 tx.begin(); 620 cache.remove("/a/b/c"); 621 Transaction t = cache.getTransactionManager().suspend(); 623 Thread th = new Thread () 624 { 625 public void run() 626 { 627 try 628 { 629 System.out.println(cache.printLockInfo()); 630 cache.get("/a/b/c"); 632 fail("Should not be able to get a hold of /a/b/c until the deleting tx completes"); 633 } 634 catch (Exception e) 635 { 636 } 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 , NotSupportedException , HeuristicMixedException , HeuristicRollbackException , RollbackException 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 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 , NotSupportedException , HeuristicMixedException , HeuristicRollbackException , RollbackException 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 , NotSupportedException 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 m = new HashMap (); 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 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 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 t) 773 { 774 t.printStackTrace(); 775 fail(t.toString()); 776 } 777 } 778 779 782 public void testPutDataRollback1() 783 { 784 try 785 { 786 cache.put("/bela/ban", null); tx.begin(); 788 Map m = new HashMap (); 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 t) 799 { 800 t.printStackTrace(); 801 fail(t.toString()); 802 } 803 } 804 805 808 public void testputDataRollback2() 809 { 810 Map m1, m2; 811 m1 = new HashMap (); 812 m1.put("name", "Bela"); 813 m1.put("id", 322649); 814 m2 = new HashMap (); 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 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 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); 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 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"); 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 t) 875 { 876 t.printStackTrace(); 877 fail(t.toString()); 878 } 879 } 880 881 882 public void testSimpleRollbackTransactions() throws Exception 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")); } 901 902 903 private Transaction startTransaction() throws Exception 904 { 905 DummyTransactionManager mgr = DummyTransactionManager.getInstance(); 906 mgr.begin(); 907 return mgr.getTransaction(); 908 } 909 910 911 public void testConcurrentReadAndWriteAccess() throws Exception 912 { 913 cache.stop(); 914 cache.getConfiguration().setIsolationLevel(IsolationLevel.REPEATABLE_READ); 915 cache.start(); 916 917 cache.put("/1/2/3/4", "foo", "bar"); 919 920 class Reader extends Thread 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"); log("RL acquired successfully"); 937 sleep(2000); 938 log("committing TX"); 939 thread_tx.commit(); log("committed TX"); 941 } 942 catch (Exception e) 943 { 944 thread_ex = e; 945 } 946 } 947 } 948 949 class Writer extends Thread 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); thread_tx = startTransaction(); 964 log("acquiring WL"); 965 cache.put("/1", "foo", "bar2"); log("acquired WL successfully"); 967 log("committing TX"); 968 thread_tx.commit(); 969 log("committed TX"); 970 } 971 catch (Exception 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 1034 private static void log(String msg) 1035 { 1036 System.out.println(Thread.currentThread().getName() + ": " + msg); 1037 } 1038 1039 1098 1144 1160 1161 public static Test suite() throws Exception 1162 { 1163 return new TestSuite(TransactionTest.class); 1164 } 1165 1166 public static void main(String [] args) throws Exception 1167 { 1168 junit.textui.TestRunner.run(suite()); 1169 } 1170 1171 1172} 1173 | Popular Tags |