private void testSavepoint() { MVStore s = MVStore.open(null); TransactionStore ts = new TransactionStore(s); Transaction tx; TransactionMap<String, String> m; tx = ts.begin(); m = tx.openMap("test"); m.put("1", "Hello"); m.put("2", "World"); m.put("1", "Hallo"); m.remove("2"); m.put("3", "!"); long logId = tx.setSavepoint(); m.put("1", "Hi"); m.put("2", "."); m.remove("3"); tx.rollbackToSavepoint(logId); assertEquals("Hallo", m.get("1")); assertNull(m.get("2")); assertEquals("!", m.get("3")); tx.rollback(); tx = ts.begin(); m = tx.openMap("test"); assertNull(m.get("1")); assertNull(m.get("2")); assertNull(m.get("3")); ts.close(); s.close(); }
private void testKeyIterator() { MVStore s = MVStore.open(null); TransactionStore ts = new TransactionStore(s); Transaction tx, tx2; TransactionMap<String, String> m, m2; Iterator<String> it, it2; tx = ts.begin(); m = tx.openMap("test"); m.put("1", "Hello"); m.put("2", "World"); m.put("3", "."); tx.commit(); tx2 = ts.begin(); m2 = tx2.openMap("test"); m2.remove("2"); m2.put("3", "!"); m2.put("4", "?"); tx = ts.begin(); m = tx.openMap("test"); it = m.keyIterator(null); assertTrue(it.hasNext()); assertEquals("1", it.next()); assertTrue(it.hasNext()); assertEquals("2", it.next()); assertTrue(it.hasNext()); assertEquals("3", it.next()); assertFalse(it.hasNext()); it2 = m2.keyIterator(null); assertTrue(it2.hasNext()); assertEquals("1", it2.next()); assertTrue(it2.hasNext()); assertEquals("3", it2.next()); assertTrue(it2.hasNext()); assertEquals("4", it2.next()); assertFalse(it2.hasNext()); s.close(); }
@Override public void add(Session session, Row row) { if (mainIndexColumn == -1) { if (row.getKey() == 0) { row.setKey(++lastKey); } } else { long c = row.getValue(mainIndexColumn).getLong(); row.setKey(c); } if (mvTable.getContainsLargeObject()) { for (int i = 0, len = row.getColumnCount(); i < len; i++) { Value v = row.getValue(i); Value v2 = v.link(database, getId()); if (v2.isLinked()) { session.unlinkAtCommitStop(v2); } if (v != v2) { row.setValue(i, v2); } } } TransactionMap<Value, Value> map = getMap(session); Value key = ValueLong.get(row.getKey()); Value old = map.getLatest(key); if (old != null) { String sql = "PRIMARY KEY ON " + table.getSQL(); if (mainIndexColumn >= 0 && mainIndexColumn < indexColumns.length) { sql += "(" + indexColumns[mainIndexColumn].getSQL() + ")"; } DbException e = DbException.get(ErrorCode.DUPLICATE_KEY_1, sql); e.setSource(this); throw e; } try { map.put(key, ValueArray.get(row.getValueList())); } catch (IllegalStateException e) { throw DbException.get(ErrorCode.CONCURRENT_UPDATE_1, table.getName()); } lastKey = Math.max(lastKey, row.getKey()); }
private void testSingleConnection() { MVStore s = MVStore.open(null); TransactionStore ts = new TransactionStore(s); Transaction tx; TransactionMap<String, String> m; // add, rollback tx = ts.begin(); m = tx.openMap("test"); m.put("1", "Hello"); assertEquals("Hello", m.get("1")); m.put("2", "World"); assertEquals("World", m.get("2")); tx.rollback(); tx = ts.begin(); m = tx.openMap("test"); assertNull(m.get("1")); assertNull(m.get("2")); // add, commit tx = ts.begin(); m = tx.openMap("test"); m.put("1", "Hello"); m.put("2", "World"); assertEquals("Hello", m.get("1")); assertEquals("World", m.get("2")); tx.commit(); tx = ts.begin(); m = tx.openMap("test"); assertEquals("Hello", m.get("1")); assertEquals("World", m.get("2")); // update+delete+insert, rollback tx = ts.begin(); m = tx.openMap("test"); m.put("1", "Hallo"); m.remove("2"); m.put("3", "!"); assertEquals("Hallo", m.get("1")); assertNull(m.get("2")); assertEquals("!", m.get("3")); tx.rollback(); tx = ts.begin(); m = tx.openMap("test"); assertEquals("Hello", m.get("1")); assertEquals("World", m.get("2")); assertNull(m.get("3")); // update+delete+insert, commit tx = ts.begin(); m = tx.openMap("test"); m.put("1", "Hallo"); m.remove("2"); m.put("3", "!"); assertEquals("Hallo", m.get("1")); assertNull(m.get("2")); assertEquals("!", m.get("3")); tx.commit(); tx = ts.begin(); m = tx.openMap("test"); assertEquals("Hallo", m.get("1")); assertNull(m.get("2")); assertEquals("!", m.get("3")); ts.close(); s.close(); }
private void testConcurrentTransactionsReadCommitted() { MVStore s = MVStore.open(null); TransactionStore ts = new TransactionStore(s); Transaction tx1, tx2; TransactionMap<String, String> m1, m2; tx1 = ts.begin(); m1 = tx1.openMap("test"); m1.put("1", "Hi"); m1.put("3", "."); tx1.commit(); tx1 = ts.begin(); m1 = tx1.openMap("test"); m1.put("1", "Hello"); m1.put("2", "World"); m1.remove("3"); tx1.commit(); // start new transaction to read old data tx2 = ts.begin(); m2 = tx2.openMap("test"); // start transaction tx1, update/delete/add tx1 = ts.begin(); m1 = tx1.openMap("test"); m1.put("1", "Hallo"); m1.remove("2"); m1.put("3", "!"); assertEquals("Hello", m2.get("1")); assertEquals("World", m2.get("2")); assertNull(m2.get("3")); tx1.commit(); assertEquals("Hallo", m2.get("1")); assertNull(m2.get("2")); assertEquals("!", m2.get("3")); tx1 = ts.begin(); m1 = tx1.openMap("test"); m1.put("2", "World"); assertNull(m2.get("2")); assertFalse(m2.tryRemove("2")); assertFalse(m2.tryPut("2", "Welt")); tx2 = ts.begin(); m2 = tx2.openMap("test"); assertNull(m2.get("2")); m1.remove("2"); assertNull(m2.get("2")); tx1.commit(); tx1 = ts.begin(); m1 = tx1.openMap("test"); assertNull(m1.get("2")); m1.put("2", "World"); m1.put("2", "Welt"); tx1.rollback(); tx1 = ts.begin(); m1 = tx1.openMap("test"); assertNull(m1.get("2")); ts.close(); s.close(); }
private void testStopWhileCommitting() throws Exception { String fileName = getBaseDir() + "/testStopWhileCommitting.h3"; FileUtils.delete(fileName); Random r = new Random(0); for (int i = 0; i < 10; ) { MVStore s; TransactionStore ts; Transaction tx; TransactionMap<Integer, String> m; s = MVStore.open(fileName); ts = new TransactionStore(s); tx = ts.begin(); s.setReuseSpace(false); m = tx.openMap("test"); final String value = "x" + i; for (int j = 0; j < 1000; j++) { m.put(j, value); } final AtomicInteger state = new AtomicInteger(); final MVStore store = s; final MVMap<Integer, String> other = s.openMap("other"); Task task = new Task() { @Override public void call() throws Exception { for (int i = 0; !stop; i++) { state.set(i); other.put(i, value); store.commit(); } } }; task.execute(); // wait for the task to start while (state.get() < 1) { Thread.yield(); } // commit while writing in the task tx.commit(); // wait for the task to stop task.get(); store.close(); s = MVStore.open(fileName); // roll back a bit, until we have some undo log entries assertTrue(s.hasMap("undoLog")); for (int back = 0; back < 100; back++) { int minus = r.nextInt(10); s.rollbackTo(Math.max(0, s.getCurrentVersion() - minus)); MVMap<?, ?> undo = s.openMap("undoLog"); if (undo.size() > 0) { break; } } ts = new TransactionStore(s); List<Transaction> list = ts.getOpenTransactions(); if (list.size() != 0) { tx = list.get(0); if (tx.getStatus() == Transaction.STATUS_COMMITTING) { i++; } } s.close(); FileUtils.delete(fileName); assertFalse(FileUtils.exists(fileName)); } }
private void testTwoPhaseCommit() { String fileName = getBaseDir() + "/testTwoPhaseCommit.h3"; FileUtils.delete(fileName); MVStore s; TransactionStore ts; Transaction tx; Transaction txOld; TransactionMap<String, String> m; List<Transaction> list; s = MVStore.open(fileName); ts = new TransactionStore(s); tx = ts.begin(); assertEquals(null, tx.getName()); tx.setName("first transaction"); assertEquals("first transaction", tx.getName()); assertEquals(0, tx.getId()); assertEquals(Transaction.STATUS_OPEN, tx.getStatus()); m = tx.openMap("test"); m.put("1", "Hello"); list = ts.getOpenTransactions(); assertEquals(1, list.size()); txOld = list.get(0); assertTrue(tx.getId() == txOld.getId()); s.commit(); ts.close(); s.close(); s = MVStore.open(fileName); ts = new TransactionStore(s); tx = ts.begin(); assertEquals(1, tx.getId()); m = tx.openMap("test"); assertEquals(null, m.get("1")); m.put("2", "Hello"); list = ts.getOpenTransactions(); assertEquals(2, list.size()); txOld = list.get(0); assertEquals(0, txOld.getId()); assertEquals(Transaction.STATUS_OPEN, txOld.getStatus()); assertEquals("first transaction", txOld.getName()); txOld.prepare(); assertEquals(Transaction.STATUS_PREPARED, txOld.getStatus()); s.commit(); s.close(); s = MVStore.open(fileName); ts = new TransactionStore(s); tx = ts.begin(); m = tx.openMap("test"); // TransactionStore was not closed, so we lost some ids assertEquals(65, tx.getId()); list = ts.getOpenTransactions(); assertEquals(2, list.size()); txOld = list.get(1); assertEquals(1, txOld.getId()); assertEquals(Transaction.STATUS_OPEN, txOld.getStatus()); assertEquals(null, txOld.getName()); txOld.rollback(); txOld = list.get(0); assertEquals(0, txOld.getId()); assertEquals(Transaction.STATUS_PREPARED, txOld.getStatus()); assertEquals("first transaction", txOld.getName()); txOld.commit(); assertEquals("Hello", m.get("1")); s.close(); FileUtils.delete(fileName); }
private void testGetModifiedMaps() { MVStore s = MVStore.open(null); TransactionStore ts = new TransactionStore(s); Transaction tx; TransactionMap<String, String> m1, m2, m3; long sp; tx = ts.begin(); m1 = tx.openMap("m1"); m2 = tx.openMap("m2"); m3 = tx.openMap("m3"); assertFalse(tx.getChanges(0).hasNext()); tx.commit(); tx = ts.begin(); m1 = tx.openMap("m1"); m2 = tx.openMap("m2"); m3 = tx.openMap("m3"); m1.put("1", "100"); sp = tx.setSavepoint(); m2.put("1", "100"); m3.put("1", "100"); Iterator<Change> it = tx.getChanges(sp); assertTrue(it.hasNext()); Change c; c = it.next(); assertEquals("m3", c.mapName); assertEquals("1", c.key.toString()); assertNull(c.value); assertTrue(it.hasNext()); c = it.next(); assertEquals("m2", c.mapName); assertEquals("1", c.key.toString()); assertNull(c.value); assertFalse(it.hasNext()); it = tx.getChanges(0); assertTrue(it.hasNext()); c = it.next(); assertEquals("m3", c.mapName); assertEquals("1", c.key.toString()); assertNull(c.value); assertTrue(it.hasNext()); c = it.next(); assertEquals("m2", c.mapName); assertEquals("1", c.key.toString()); assertNull(c.value); assertTrue(it.hasNext()); c = it.next(); assertEquals("m1", c.mapName); assertEquals("1", c.key.toString()); assertNull(c.value); assertFalse(it.hasNext()); tx.rollbackToSavepoint(sp); it = tx.getChanges(0); assertTrue(it.hasNext()); c = it.next(); assertEquals("m1", c.mapName); assertEquals("1", c.key.toString()); assertNull(c.value); assertFalse(it.hasNext()); tx.commit(); s.close(); }