📄 transactiontest.java
字号:
abortTest(false); } public void testExplicitAbort() throws Exception { abortTest(true); } private void abortTest(final boolean explicit) throws Exception { final TransactionRunner runner = new TransactionRunner(env); runner.setAllowNestedTransactions(DbCompat.NESTED_TRANSACTIONS); assertNull(currentTxn.getTransaction()); runner.run(new TransactionWorker() { public void doWork() throws Exception { final Transaction txn1 = currentTxn.getTransaction(); assertNotNull(txn1); assertNull(map.put(ONE, ONE)); assertEquals(ONE, map.get(ONE)); if (DbCompat.NESTED_TRANSACTIONS) { try { runner.run(new TransactionWorker() { public void doWork() throws Exception { final Transaction txn2 = currentTxn.getTransaction(); assertNotNull(txn2); assertTrue(txn1 != txn2); assertNull(map.put(TWO, TWO)); assertEquals(TWO, map.get(TWO)); if (explicit) { currentTxn.abortTransaction(); } else { throw new IllegalArgumentException( "test-abort"); } } }); assertTrue(explicit); } catch (IllegalArgumentException e) { assertTrue(!explicit); assertEquals("test-abort", e.getMessage()); } } Transaction txn3 = currentTxn.getTransaction(); assertSame(txn1, txn3); assertEquals(ONE, map.get(ONE)); assertNull(map.get(TWO)); } }); assertNull(currentTxn.getTransaction()); } public void testReadCommittedCollection() throws Exception { StoredSortedMap degree2Map = (StoredSortedMap) StoredCollections.configuredSortedMap (map, CursorConfig.READ_COMMITTED); // original map is not read-committed assertTrue(!isReadCommitted(map)); // all read-committed containers are read-uncommitted assertTrue(isReadCommitted(degree2Map)); assertTrue(isReadCommitted (StoredCollections.configuredMap (map, CursorConfig.READ_COMMITTED))); assertTrue(isReadCommitted (StoredCollections.configuredCollection (map.values(), CursorConfig.READ_COMMITTED))); assertTrue(isReadCommitted (StoredCollections.configuredSet (map.keySet(), CursorConfig.READ_COMMITTED))); assertTrue(isReadCommitted (StoredCollections.configuredSortedSet ((SortedSet) map.keySet(), CursorConfig.READ_COMMITTED))); if (DbCompat.RECNO_METHOD) { // create a list just so we can call configuredList() Database listStore = TestStore.RECNO_RENUM.open(env, null); List list = new StoredList(listStore, TestStore.VALUE_BINDING, true); assertTrue(isReadCommitted (StoredCollections.configuredList (list, CursorConfig.READ_COMMITTED))); listStore.close(); } map.put(ONE, ONE); doReadCommitted(degree2Map, null); } private static boolean isReadCommitted(Object container) { StoredContainer storedContainer = (StoredContainer) container; /* We can't use getReadCommitted until is is added to DB core. */ return storedContainer.getCursorConfig() != null && storedContainer.getCursorConfig().getReadCommitted(); } public void testReadCommittedTransaction() throws Exception { TransactionConfig config = new TransactionConfig(); config.setReadCommitted(true); doReadCommitted(map, config); } private void doReadCommitted(final StoredSortedMap degree2Map, TransactionConfig txnConfig) throws Exception { map.put(ONE, ONE); TransactionRunner runner = new TransactionRunner(env); runner.setTransactionConfig(txnConfig); assertNull(currentTxn.getTransaction()); runner.run(new TransactionWorker() { public void doWork() throws Exception { assertNotNull(currentTxn.getTransaction()); /* Do a read-committed get(), the lock is not retained. */ assertEquals(ONE, degree2Map.get(ONE)); /* * If we were not using read-committed, the following write of * key ONE with an auto-commit transaction would self-deadlock * since two transactions in the same thread would be * attempting to lock the same key, one for write and one for * read. This test passes if we do not deadlock. */ DatabaseEntry key = new DatabaseEntry(); DatabaseEntry value = new DatabaseEntry(); testStore.getKeyBinding().objectToEntry(ONE, key); testStore.getValueBinding().objectToEntry(TWO, value); store.put(null, key, value); } }); assertNull(currentTxn.getTransaction()); } public void testReadUncommittedCollection() throws Exception { StoredSortedMap dirtyMap = (StoredSortedMap) StoredCollections.configuredSortedMap (map, CursorConfig.READ_UNCOMMITTED); // original map is not read-uncommitted assertTrue(!isReadUncommitted(map)); // all read-uncommitted containers are read-uncommitted assertTrue(isReadUncommitted(dirtyMap)); assertTrue(isReadUncommitted (StoredCollections.configuredMap (map, CursorConfig.READ_UNCOMMITTED))); assertTrue(isReadUncommitted (StoredCollections.configuredCollection (map.values(), CursorConfig.READ_UNCOMMITTED))); assertTrue(isReadUncommitted (StoredCollections.configuredSet (map.keySet(), CursorConfig.READ_UNCOMMITTED))); assertTrue(isReadUncommitted (StoredCollections.configuredSortedSet ((SortedSet) map.keySet(), CursorConfig.READ_UNCOMMITTED))); if (DbCompat.RECNO_METHOD) { // create a list just so we can call configuredList() Database listStore = TestStore.RECNO_RENUM.open(env, null); List list = new StoredList(listStore, TestStore.VALUE_BINDING, true); assertTrue(isReadUncommitted (StoredCollections.configuredList (list, CursorConfig.READ_UNCOMMITTED))); listStore.close(); } doReadUncommitted(dirtyMap); } private static boolean isReadUncommitted(Object container) { StoredContainer storedContainer = (StoredContainer) container; return storedContainer.getCursorConfig() != null && storedContainer.getCursorConfig().getReadUncommitted(); } public void testReadUncommittedTransaction() throws Exception { TransactionRunner runner = new TransactionRunner(env); TransactionConfig config = new TransactionConfig(); config.setReadUncommitted(true); runner.setTransactionConfig(config); assertNull(currentTxn.getTransaction()); runner.run(new TransactionWorker() { public void doWork() throws Exception { assertNotNull(currentTxn.getTransaction()); doReadUncommitted(map); } }); assertNull(currentTxn.getTransaction()); } private synchronized void doReadUncommitted(StoredSortedMap dirtyMap) throws Exception { // start thread one ReadUncommittedThreadOne t1 = new ReadUncommittedThreadOne(env, this); t1.start(); wait(); // put ONE synchronized (t1) { t1.notify(); } wait(); readCheck(dirtyMap, ONE, ONE); assertTrue(!dirtyMap.isEmpty()); // abort ONE synchronized (t1) { t1.notify(); } t1.join(); readCheck(dirtyMap, ONE, null); assertTrue(dirtyMap.isEmpty()); // start thread two ReadUncommittedThreadTwo t2 = new ReadUncommittedThreadTwo(env, this); t2.start(); wait(); // put TWO synchronized (t2) { t2.notify(); } wait(); readCheck(dirtyMap, TWO, TWO); assertTrue(!dirtyMap.isEmpty()); // commit TWO synchronized (t2) { t2.notify(); } t2.join(); readCheck(dirtyMap, TWO, TWO); assertTrue(!dirtyMap.isEmpty()); } private static class ReadUncommittedThreadOne extends Thread { private CurrentTransaction currentTxn; private TransactionTest parent; private StoredSortedMap map; private ReadUncommittedThreadOne(Environment env, TransactionTest parent) { this.currentTxn = CurrentTransaction.getInstance(env); this.parent = parent; this.map = parent.map; } public synchronized void run() { try { assertNull(currentTxn.getTransaction()); assertNotNull(currentTxn.beginTransaction(null)); assertNotNull(currentTxn.getTransaction()); readCheck(map, ONE, null); synchronized (parent) { parent.notify(); } wait(); // put ONE assertNull(map.put(ONE, ONE)); readCheck(map, ONE, ONE); synchronized (parent) { parent.notify(); } wait(); // abort ONE assertNull(currentTxn.abortTransaction()); assertNull(currentTxn.getTransaction()); } catch (Exception e) { throw new RuntimeExceptionWrapper(e); } } } private static class ReadUncommittedThreadTwo extends Thread { private Environment env; private CurrentTransaction currentTxn; private TransactionTest parent; private StoredSortedMap map; private ReadUncommittedThreadTwo(Environment env, TransactionTest parent) { this.env = env; this.currentTxn = CurrentTransaction.getInstance(env); this.parent = parent; this.map = parent.map; } public synchronized void run() { try { final TransactionRunner runner = new TransactionRunner(env); final Object thread = this; assertNull(currentTxn.getTransaction()); runner.run(new TransactionWorker() { public void doWork() throws Exception { assertNotNull(currentTxn.getTransaction()); readCheck(map, TWO, null); synchronized (parent) { parent.notify(); } thread.wait(); // put TWO assertNull(map.put(TWO, TWO)); readCheck(map, TWO, TWO); synchronized (parent) { parent.notify(); } thread.wait(); // commit TWO } }); assertNull(currentTxn.getTransaction()); } catch (Exception e) { throw new RuntimeExceptionWrapper(e); } } } private static void readCheck(StoredSortedMap checkMap, Object key, Object expect) { if (expect == null) { assertNull(checkMap.get(key)); assertTrue(checkMap.tailMap(key).isEmpty()); assertTrue(!checkMap.tailMap(key).containsKey(key)); assertTrue(!checkMap.keySet().contains(key)); assertTrue(checkMap.duplicates(key).isEmpty()); Iterator i = checkMap.keySet().iterator(); try { while (i.hasNext()) { assertTrue(!key.equals(i.next())); } } finally { StoredIterator.close(i); } } else { assertEquals(expect, checkMap.get(key)); assertEquals(expect, checkMap.tailMap(key).get(key)); assertTrue(!checkMap.tailMap(key).isEmpty()); assertTrue(checkMap.tailMap(key).containsKey(key)); assertTrue(checkMap.keySet().contains(key)); assertTrue(checkMap.values().contains(expect)); assertTrue(!checkMap.duplicates(key).isEmpty()); assertTrue(checkMap.duplicates(key).contains(expect)); Iterator i = checkMap.keySet().iterator(); try { boolean found = false; while (i.hasNext()) { if (expect.equals(i.next())) { found = true; } } assertTrue(found); } finally { StoredIterator.close(i); } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -