/** * Checks that gets work for implicit txs. * * @param cache Cache to test. * @throws Exception If failed. */ private void checkExplicitTx(Ignite ignite, IgniteCache<String, String> cache) throws Exception { IgniteCache<String, String> asyncCache = cache.withAsync(); Transaction tx = ignite.transactions().txStart(); try { assertNull(cache.get("key1")); tx.commit(); } finally { tx.close(); } tx = ignite.transactions().txStart(); try { asyncCache.get("key2"); assertNull(asyncCache.future().get()); tx.commit(); } finally { tx.close(); } tx = ignite.transactions().txStart(); try { assertTrue(cache.getAll(F.asSet("key3", "key4")).isEmpty()); tx.commit(); } finally { tx.close(); } tx = ignite.transactions().txStart(); try { asyncCache.getAll(F.asSet("key5", "key6")); assertTrue(((Map) asyncCache.future().get()).isEmpty()); tx.commit(); } finally { tx.close(); } tx = ignite.transactions().txStart(); try { cache.put("key7", "key7"); cache.remove("key7"); assertNull(cache.get("key7")); tx.commit(); } finally { tx.close(); } checkEmpty(cache); }
/** @throws Exception In case of error. */ public void testPutWithExpiration() throws Exception { IgniteCache<String, String> cache1 = ignite1.cache(null); IgniteCache<String, String> cache2 = ignite2.cache(null); IgniteCache<String, String> cache3 = ignite3.cache(null); cache1.put("key", "val"); Transaction tx = ignite1.transactions().txStart(); long ttl = 500; cache1 .withExpiryPolicy(new TouchedExpiryPolicy(new Duration(MILLISECONDS, ttl))) .put("key", "val"); assert cache1.get("key") != null; tx.commit(); info("Going to sleep for: " + (ttl + 1000)); // Allow for expiration. Thread.sleep(ttl + 1000); String v1 = cache1.get("key"); String v2 = cache2.get("key"); String v3 = cache3.get("key"); assert v1 == null : "V1 should be null: " + v1; assert v2 == null : "V2 should be null: " + v2; assert v3 == null : "V3 should be null: " + v3; }
/** * @param id Transaction ID. * @return Transaction state. */ private int txClose(long id) { Transaction tx = tx(id); try { tx.close(); return tx.state().ordinal(); } finally { unregisterTx(id); } }
/** * Executes transaction with read/write-through to persistent store. * * @param cache Cache to execute transaction on. */ private static void executeTransaction(IgniteCache<Long, Person> cache) { try (Transaction tx = Ignition.ignite().transactions().txStart()) { Person val = cache.get(id); System.out.println("Read value: " + val); val = cache.getAndPut(id, new Person(id, "Isaac", "Newton")); System.out.println("Overwrote old value: " + val); val = cache.get(id); System.out.println("Read value: " + val); tx.commit(); } System.out.println("Read value after commit: " + cache.get(id)); }
/** {@inheritDoc} */ @Override protected long processInStreamOutLong(int type, BinaryRawReaderEx reader) throws IgniteCheckedException { long txId = reader.readLong(); final Transaction asyncTx = (Transaction) tx(txId).withAsync(); switch (type) { case OP_COMMIT_ASYNC: asyncTx.commit(); break; case OP_ROLLBACK_ASYNC: asyncTx.rollback(); break; default: return super.processInStreamOutLong(type, reader); } // Future result is the tx itself, we do not want to return it to the platform. IgniteFuture fut = asyncTx .future() .chain( new C1<IgniteFuture, Object>() { private static final long serialVersionUID = 0L; @Override public Object apply(IgniteFuture fut) { return null; } }); readAndListenFuture(reader, fut); return TRUE; }
/** * @param ignite Ignite instance. * @param clo Closure. * @return Result of closure execution. * @throws Exception If failed. */ protected <T> T doInTransaction(Ignite ignite, Callable<T> clo) throws Exception { while (true) { try (Transaction tx = ignite.transactions().txStart(PESSIMISTIC, REPEATABLE_READ)) { T res = clo.call(); tx.commit(); return res; } catch (CacheException e) { if (e.getCause() instanceof ClusterTopologyException) { ClusterTopologyException topEx = (ClusterTopologyException) e.getCause(); topEx.retryReadyFuture().get(); } else throw e; } catch (ClusterTopologyException e) { IgniteFuture<?> fut = e.retryReadyFuture(); fut.get(); } catch (TransactionRollbackException ignore) { // Safe to retry right away. } } }
/** {@inheritDoc} */ @Override protected void afterTest() throws Exception { Transaction tx = jcache().unwrap(Ignite.class).transactions().tx(); if (tx != null) { tx.close(); fail("Cache transaction remained after test completion: " + tx); } for (int i = 0; i < gridCount(); i++) { info("Checking grid: " + i); while (true) { try { final int fi = i; assertTrue( "Cache is not empty: " + " localSize = " + jcache(fi).localSize(CachePeekMode.ALL) + ", local entries " + entrySet(jcache(fi).localEntries()), GridTestUtils.waitForCondition( // Preloading may happen as nodes leave, so we need to wait. new GridAbsPredicateX() { @Override public boolean applyx() throws IgniteCheckedException { jcache(fi).removeAll(); if (jcache(fi).size(CachePeekMode.ALL) > 0) { for (Cache.Entry<String, ?> k : jcache(fi).localEntries()) jcache(fi).remove(k.getKey()); } return jcache(fi).localSize(CachePeekMode.ALL) == 0; } }, getTestTimeout())); int primaryKeySize = jcache(i).localSize(CachePeekMode.PRIMARY); int keySize = jcache(i).localSize(); int size = jcache(i).localSize(); int globalSize = jcache(i).size(); int globalPrimarySize = jcache(i).size(CachePeekMode.PRIMARY); info( "Size after [idx=" + i + ", size=" + size + ", keySize=" + keySize + ", primarySize=" + primaryKeySize + ", globalSize=" + globalSize + ", globalPrimarySize=" + globalPrimarySize + ", entrySet=" + jcache(i).localEntries() + ']'); assertEquals( "Cache is not empty [idx=" + i + ", entrySet=" + jcache(i).localEntries() + ']', 0, jcache(i).localSize(CachePeekMode.ALL)); break; } catch (Exception e) { if (X.hasCause(e, ClusterTopologyCheckedException.class)) { info("Got topology exception while tear down (will retry in 1000ms)."); U.sleep(1000); } else throw e; } } for (Cache.Entry<String, Integer> entry : jcache(i).localEntries(CachePeekMode.SWAP)) jcache(i).remove(entry.getKey()); } assert jcache().unwrap(Ignite.class).transactions().tx() == null; assertEquals("Cache is not empty", 0, jcache().localSize(CachePeekMode.ALL)); resetStore(); }
/** @throws IgniteCheckedException If test fails. */ public void testOptimisticTransaction() throws Exception { CountDownLatch latch = new CountDownLatch(9); IgnitePredicate<Event> lsnr = new CacheEventListener(latch); try { IgniteCache<String, String> cache1 = ignite1.cache(null); IgniteCache<String, String> cache2 = ignite2.cache(null); IgniteCache<String, String> cache3 = ignite3.cache(null); ignite1.events().localListen(lsnr, EVT_CACHE_OBJECT_PUT, EVT_CACHE_OBJECT_REMOVED); ignite2.events().localListen(lsnr, EVT_CACHE_OBJECT_PUT, EVT_CACHE_OBJECT_REMOVED); ignite3.events().localListen(lsnr, EVT_CACHE_OBJECT_PUT, EVT_CACHE_OBJECT_REMOVED); Transaction tx = ignite1.transactions().txStart(OPTIMISTIC, READ_COMMITTED, 0, 0); try { cache1.put("tx1", "val1"); cache1.put("tx2", "val2"); cache1.put("tx3", "val3"); assert cache2.get("tx1") == null; assert cache2.get("tx2") == null; assert cache2.get("tx3") == null; assert cache3.get("tx1") == null; assert cache3.get("tx2") == null; assert cache3.get("tx3") == null; tx.commit(); } catch (CacheException e) { tx.rollback(); throw e; } assert latch.await(5, SECONDS); String b1 = cache2.get("tx1"); String b2 = cache2.get("tx2"); String b3 = cache2.get("tx3"); String c1 = cache3.get("tx1"); String c2 = cache3.get("tx2"); String c3 = cache3.get("tx3"); assert b1 != null : "Invalid value: " + b1; assert b2 != null : "Invalid value: " + b2; assert b3 != null : "Invalid value: " + b3; assert c1 != null : "Invalid value: " + c1; assert c2 != null : "Invalid value: " + c2; assert c3 != null : "Invalid value: " + c3; assert "val1".equals(b1); assert "val2".equals(b2); assert "val3".equals(b3); assert "val1".equals(c1); assert "val2".equals(c2); assert "val3".equals(c3); } finally { ignite1.events().stopLocalListen(lsnr); ignite2.events().stopLocalListen(lsnr); ignite3.events().stopLocalListen(lsnr); } }