@Override public void run() { doSleep(delay); tx.rollback(); } }, 1, "tx-rollback-thread");
@Override public void applyx(Transaction tx) throws Exception { tx.rollback(); } },
@Override public Void call() throws Exception { IgniteCache<Object, Object> cache = node.cache(DEFAULT_CACHE_NAME); try (Transaction tx = node.transactions().txStart(PESSIMISTIC, REPEATABLE_READ)) { assertEquals(0, checkAndGet(false, cache, 0, SCAN, GET)); readStart.countDown(); assertTrue(readProceed.await(5, TimeUnit.SECONDS)); assertEquals(0, checkAndGet(true, cache, 1, GET, SCAN)); assertEquals(0, checkAndGet(true, cache, 2, GET, SCAN)); Map<Object, Object> res = checkAndGetAll(true, cache, startVals.keySet(), GET, SCAN); assertEquals(startVals.size(), res.size()); for (Map.Entry<Object, Object> e : res.entrySet()) assertEquals("Invalid value for key: " + e.getKey(), 0, e.getValue()); tx.rollback(); } return null; } });
@Override public Void call() throws Exception { spi.waitForBlocked(); client.transactions().localActiveTransactions().iterator().next().rollback(); return null; } }, "tx-rollback-thread");
/** {@inheritDoc} */ @Override protected void doRollback(DefaultTransactionStatus status) throws TransactionException { IgniteTransactionObject txObj = (IgniteTransactionObject)status.getTransaction(); Transaction tx = txObj.getTransactionHolder().getTransaction(); if (status.isDebug() && log.isDebugEnabled()) log.debug("Rolling back Ignite transaction: " + tx); try { tx.rollback(); } catch (IgniteException e) { throw new TransactionSystemException("Could not rollback Ignite transaction", e); } }
@Override public Object call() throws Exception { Map<Integer, Integer> res = null; if (readInTx) { try (Transaction tx = getNode.transactions().txStart(PESSIMISTIC, REPEATABLE_READ)) { res = readAllByMode(cache, keys, readMode, INTEGER_CODEC); tx.rollback(); } catch (Exception e) { handleTxException(e); } } else res = readAllByMode(cache, keys, readMode, INTEGER_CODEC); assertTrue((res != null || readInTx) || (res != null && 20 == res.size())); if (res != null) { Integer val = null; for (Integer val0 : res.values()) { assertNotNull(val0); if (val == null) val = val0; else assertEquals("res=" + res, val, val0); } } return null; } }, "get-thread");
@Override public void apply(Integer idx) { ThreadLocalRandom rnd = ThreadLocalRandom.current(); Ignite node = ignite(idx % NODES); IgniteTransactions txs = node.transactions(); IgniteCache cache = node.cache(DEFAULT_CACHE_NAME); while (System.currentTimeMillis() < stopTime) { int keyCnt = rnd.nextInt(10) + 1; Set<Integer> keys = new HashSet<>(); for (int i = 0; i < keyCnt; i++) keys.add(rnd.nextInt()); if (tx) { try (Transaction tx = txs.txStart(PESSIMISTIC, REPEATABLE_READ)) { cache.getAll(keys); if (rnd.nextBoolean()) tx.commit(); else tx.rollback(); } } else cache.getAll(keys); } } }, NODES * 2, "get-thread");
@Override public void run() throws Exception { try (Transaction tx = ignite.transactions().txStart(concurrency, isolation)) { final Map<Integer, EntryProcessorResult<Object>> r = cache.invokeAll(F.asMap( key1, new TestEntryProcessor(okValue), key2, new TestEntryProcessor(badValue))); assertNotNull(r); GridTestUtils.assertThrows(log, new Callable<Object>() { @Override public Object call() throws Exception { return r.get(key2).get(); } }, EntryProcessorException.class, ERR_MSG); tx.rollback(); } assertEquals(0, cache.size()); } });
/** * @throws Exception If failed. */ @Test public void testSelectForUpdateAfterAbortedTx() throws Exception { assert disableScheduledVacuum; Ignite node = grid(0); IgniteCache<Integer, ?> cache = node.cache("Person"); List<List<?>> res; try (Transaction tx = node.transactions().txStart(TransactionConcurrency.PESSIMISTIC, TransactionIsolation.REPEATABLE_READ)) { res = cache.query(new SqlFieldsQuery("update person set lastName=UPPER(lastName)")).getAll(); assertEquals((long)CACHE_SIZE, res.get(0).get(0)); tx.rollback(); } try (Transaction tx = node.transactions().txStart(TransactionConcurrency.PESSIMISTIC, TransactionIsolation.REPEATABLE_READ)) { res = cache.query(new SqlFieldsQuery("select id, * from person order by id for update")).getAll(); assertEquals(CACHE_SIZE, res.size()); List<Integer> keys = new ArrayList<>(); for (List<?> r : res) keys.add((Integer)r.get(0)); checkLocks("Person", keys, true); tx.rollback(); checkLocks("Person", keys, false); } }
/** * @param tx Transaction. * @param commit Commit flag. */ protected void checkFastTxFinish(Transaction tx, boolean commit) { if (commit) tx.commit(); else tx.rollback(); IgniteInternalTx tx0 = ((TransactionProxyImpl)tx).tx(); assertNull(fieldValue(tx0, "prepFut")); assertTrue(fieldValue(tx0, "finishFut") instanceof GridNearTxFastFinishFuture); }
@Override public void applyx(Ignite ignite, final IgniteCache<Integer, Integer> cache) throws Exception { for (TransactionIsolation tx1Isolation : TransactionIsolation.values()) { for (TransactionIsolation tx2Isolation : TransactionIsolation.values()) { Transaction tx1 = ignite.transactions().txStart(OPTIMISTIC, tx1Isolation); cache.put(1, 1); tx1.suspend(); assertFalse(cache.containsKey(1)); Transaction tx2 = ignite.transactions().txStart(OPTIMISTIC, tx2Isolation); cache.put(1, 2); tx2.suspend(); assertFalse(cache.containsKey(1)); tx1.resume(); assertEquals(1, (int)cache.get(1)); tx1.suspend(); tx2.resume(); assertEquals(2, (int)cache.get(1)); tx2.rollback(); tx1.resume(); tx1.rollback(); cache.removeAll(); } } } });
/** */ private void checkPeekDoesNotSeeAbortedVersions() throws Exception { Integer pk = primaryKey(cache); cache.put(pk, 1); try (Transaction tx = grid(0).transactions().txStart(PESSIMISTIC, REPEATABLE_READ)) { cache.put(pk, 2); tx.rollback(); } assertEquals(1, cache.localPeek(pk)); }
/** * @throws Exception If failed. */ @Test public void testQueryInsertRollback() throws Exception { ccfg = cacheConfiguration(cacheMode(), FULL_SYNC, 2, DFLT_PARTITION_COUNT) .setIndexedTypes(Integer.class, Integer.class); startGridsMultiThreaded(4); Random rnd = ThreadLocalRandom.current(); Ignite checkNode = grid(rnd.nextInt(4)); Ignite updateNode = grid(rnd.nextInt(4)); IgniteCache cache = checkNode.cache(DEFAULT_CACHE_NAME); try (Transaction tx = updateNode.transactions().txStart(PESSIMISTIC, REPEATABLE_READ)) { tx.timeout(TX_TIMEOUT); SqlFieldsQuery qry = new SqlFieldsQuery("INSERT INTO Integer (_key, _val) values (1,1),(2,2),(3,3)"); IgniteCache<Object, Object> cache0 = updateNode.cache(DEFAULT_CACHE_NAME); try (FieldsQueryCursor<List<?>> cur = cache0.query(qry)) { assertEquals(3L, cur.iterator().next().get(0)); } qry = new SqlFieldsQuery("INSERT INTO Integer (_key, _val) values (4,4),(5,5),(6,6)"); try (FieldsQueryCursor<List<?>> cur = cache0.query(qry)) { assertEquals(3L, cur.iterator().next().get(0)); } tx.rollback(); } for (int i = 1; i <= 6; i++) assertTrue(cache.query(new SqlFieldsQuery("SELECT * FROM Integer WHERE _key = 1")).getAll().isEmpty()); }
/** * @throws Exception If failed. */ private void doPutAndRollback() throws Exception { IgniteCache<Object, Object> c = jcache(); try (Transaction tx = grid().transactions().txStart()) { c.put(1, 1); tx.rollback(); } assert c.localSize() == 0; assert c.localPeek(1, CachePeekMode.ONHEAP) == null; assert c.get(1) == null; } }
/** {@inheritDoc} */ @Override public long processInLongOutLong(int type, long val) throws IgniteCheckedException { switch (type) { case OP_PREPARE: ((TransactionProxyImpl)tx(val)).tx().prepare(true); return TRUE; case OP_COMMIT: tx(val).commit(); return txClose(val); case OP_ROLLBACK: tx(val).rollback(); return txClose(val); case OP_CLOSE: return txClose(val); case OP_SET_ROLLBACK_ONLY: return tx(val).setRollbackOnly() ? TRUE : FALSE; case OP_STATE: return tx(val).state().ordinal(); case OP_RESET_METRICS: txs.resetMetrics(); return TRUE; } return super.processInLongOutLong(type, val); }
/** * Tests isolation of system and user transactions. */ @Test public void testIsolation() { IgniteAtomicSequence seq = ignite(0).atomicSequence(SEQ_NAME, 0, true); CacheConfiguration<Object, Object> ccfg = new CacheConfiguration<>(DEFAULT_CACHE_NAME); ccfg.setAtomicityMode(TRANSACTIONAL); IgniteCache<Object, Object> cache = ignite(0).getOrCreateCache(ccfg); try (Transaction tx = ignite(0).transactions().txStart()) { seq.getAndIncrement(); cache.put(1, 1); tx.rollback(); } assertEquals(0, cache.size()); assertEquals(new Long(1L), U.field(seq, "locVal")); assertEquals(new Long(SEQ_CACHE_SIZE - 1), U.field(seq, "upBound")); }
/** * @param tx Transaction. * @param commit Commit flag. */ protected void checkNormalTxFinish(Transaction tx, boolean commit) { IgniteInternalTx tx0 = ((TransactionProxyImpl)tx).tx(); if (commit) { tx.commit(); assertNotNull(fieldValue(tx0, "prepFut")); assertNotNull(fieldValue(tx0, "finishFut")); } else { tx.rollback(); assertNull(fieldValue(tx0, "prepFut")); assertNotNull(fieldValue(tx0, "finishFut")); } }
/** * Implementation of ignite data structures internally uses special system caches, need make sure that * transaction on these system caches do not intersect with transactions started by user. * * @throws Exception If failed. */ @Test public void testIsolation() throws Exception { Ignite ignite = grid(0); IgniteCache<Object, Object> cache = ignite.cache(TRANSACTIONAL_CACHE_NAME); IgniteAtomicLong atomic = ignite.atomicLong("atomic", 0, true); long curAtomicVal = atomic.get(); try (Transaction tx = ignite.transactions().txStart()) { atomic.getAndIncrement(); cache.put(1, 1); tx.rollback(); } assertEquals(0, cache.size()); assertEquals(curAtomicVal + 1, atomic.get()); }
/** * @param loc Explicit query locality flag. * @throws Exception if failed. */ private void doTestLocalQuery(boolean loc) throws Exception { cache1.clear(); Transaction tx = ignite1.transactions().txStart(); try { cache1.put(new CacheKey(1), new CacheValue("1")); cache1.put(new CacheKey(2), new CacheValue("2")); cache1.put(new CacheKey(3), new CacheValue("3")); cache1.put(new CacheKey(4), new CacheValue("4")); tx.commit(); info("Committed transaction: " + tx); } catch (IgniteException e) { tx.rollback(); throw e; } checkLocalQueryResults(cache1, loc); checkLocalQueryResults(cache2, loc); checkLocalQueryResults(cache3, loc); }