/** * Gets DB transaction isolation level based on ongoing cache transaction isolation. * * @return DB transaction isolation. */ private TransactionDefinition definition(Transaction tx, String cacheName) { assert tx != null; DefaultTransactionDefinition def = new DefaultTransactionDefinition(); def.setName("Ignite Tx [cache=" + (cacheName != null ? cacheName : "<default>") + ", id=" + tx.xid() + ']'); def.setIsolationLevel(isolationLevel(tx.isolation())); long timeoutSec = (tx.timeout() + 500) / 1000; if (timeoutSec > 0 && timeoutSec < Integer.MAX_VALUE) def.setTimeout((int)timeoutSec); return def; }
@Override public void apply(Integer idx, List<TestCache> caches, AtomicBoolean stop) { ThreadLocalRandom rnd = ThreadLocalRandom.current(); int cnt = 0; while (!stop.get()) { TestCache<Integer, Integer> cache = randomCache(caches, rnd); IgniteTransactions txs = cache.cache.unwrap(Ignite.class).transactions(); TreeSet<Integer> keys = new TreeSet<>(); while (keys.size() < N) keys.add(rnd.nextInt(TOTAL)); try (Transaction tx = txs.txStart(PESSIMISTIC, REPEATABLE_READ)) { tx.timeout(TX_TIMEOUT); Map<Integer, Integer> curVals = readAllByMode(cache.cache, keys, readMode, INTEGER_CODEC); assertEquals(N, curVals.size()); Map<Integer, Integer> newVals = new TreeMap<>(); for (Map.Entry<Integer, Integer> e : curVals.entrySet()) newVals.put(e.getKey(), e.getValue() + 1); writeAllByMode(cache.cache, newVals, writeMode, INTEGER_CODEC); tx.commit(); } catch (Exception e) { handleTxException(e); } finally { cache.readUnlock(); } cnt++; } info("Writer finished, updates: " + cnt); } };
@Override public void write(BinaryRawWriterEx writer, Transaction tx) { writer.writeLong(registerTx(tx)); writer.writeInt(tx.concurrency().ordinal()); writer.writeInt(tx.isolation().ordinal()); writer.writeLong(tx.timeout()); } });
@Override public Void call() throws Exception { Ignite node = ignite(COORD_NODES); List<IgniteCache> caches = new ArrayList<>(); for (String cacheName : cacheNames) caches.add(node.cache(cacheName)); Integer val = 1; while (!done.get()) { Map<Integer, Integer> vals = new LinkedHashMap<>(); for (int i = 0; i < KEYS; i++) vals.put(i, val); for (IgniteCache cache : caches) { try { try (Transaction tx = node.transactions().txStart(concurrency, isolation)) { tx.timeout(TX_TIMEOUT); writeAllByMode(cache, vals, writeMode, INTEGER_CODEC); tx.commit(); } } catch (Exception e) { handleTxException(e); } } val++; } return null; } }, "putAll-thread");
@Override public void run() { IgniteEx node = grid(0); try { try (Transaction tx = node.transactions().txStart(PESSIMISTIC, REPEATABLE_READ)) { tx.timeout(TX_TIMEOUT); barrier.await(TX_TIMEOUT, TimeUnit.MILLISECONDS); IgniteCache<Object, Object> cache0 = node.cache(DEFAULT_CACHE_NAME); SqlFieldsQuery qry; synchronized (barrier) { qry = new SqlFieldsQuery("SELECT * FROM Integer"); try (FieldsQueryCursor<List<?>> cur = cache0.query(qry)) { assertEquals(1, cur.getAll().size()); } } barrier.await(TX_TIMEOUT, TimeUnit.MILLISECONDS); qry = new SqlFieldsQuery("UPDATE Integer SET _val = (_key * 10)"); try (FieldsQueryCursor<List<?>> cur = cache0.query(qry)) { assertEquals(1L, cur.iterator().next().get(0)); } tx.commit(); } } catch (Exception e) { onException(ex, e); } } }, 2, "tx-thread");
@Override public Void call() throws Exception { Ignite node = ignite(COORD_NODES); IgniteCache cache = node.cache(cacheNames.get(0)); Integer val = 0; while (!done.get()) { try { try (Transaction tx = node.transactions().txStart(concurrency, isolation)) { tx.timeout(TX_TIMEOUT); writeByMode(cache, Integer.MAX_VALUE, val, writeMode, INTEGER_CODEC); tx.commit(); } } catch (Exception e) { handleTxException(e); } val++; } return null; } }, "put-thread");
@Override public void run() { try { try (Transaction tx = checkNode.transactions().txStart(PESSIMISTIC, REPEATABLE_READ)) { tx.timeout(TX_TIMEOUT); barrier.await(); SqlFieldsQuery qry = new SqlFieldsQuery("SELECT * FROM MvccTestSqlIndexValue"); cache0.query(qry).getAll(); barrier.await(); String sqlText = "UPDATE MvccTestSqlIndexValue t SET idxVal1=" + "(SELECT _val FROM \"int\".Integer WHERE _key >= 5 AND _key <= 5 ORDER BY _key) WHERE _key = 5"; qry = new SqlFieldsQuery(sqlText); cache0.query(qry).getAll(); tx.commit(); } } catch (Exception e) { onException(ex, e); } } }, 2, "tx-thread");
@Override public Object call() throws Exception { 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),(1,2),(1,3)"); IgniteCache<Object, Object> cache0 = updateNode.cache(DEFAULT_CACHE_NAME); cache0.query(qry).getAll(); tx.commit(); } return null; } }, CacheException.class, "Duplicate key during INSERT [key=KeyCacheObjectImpl");
/** * @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()); }
@Override public void run() { int id = idx.getAndIncrement(); IgniteEx node = grid(id); try { try (Transaction tx = node.transactions().txStart(PESSIMISTIC, REPEATABLE_READ)) { if (timeoutMode == TimeoutMode.TX) tx.timeout(TIMEOUT); String sqlText = "INSERT INTO MvccTestSqlIndexValue (_key, idxVal1) " + "SELECT DISTINCT _key, _val FROM \"int\".Integer ORDER BY _key"; String sqlAsc = sqlText + " ASC"; String sqlDesc = sqlText + " DESC"; SqlFieldsQuery qry = new SqlFieldsQuery((id % 2) == 0 ? sqlAsc : sqlDesc); if (timeoutMode == TimeoutMode.STMT) qry.setTimeout(TIMEOUT, TimeUnit.MILLISECONDS); IgniteCache<Object, Object> cache0 = node.cache(DEFAULT_CACHE_NAME); cache0.query(qry).getAll(); barrier.await(); qry = new SqlFieldsQuery((id % 2) == 0 ? sqlDesc : sqlAsc); if (timeoutMode == TimeoutMode.STMT) qry.setTimeout(TIMEOUT, TimeUnit.MILLISECONDS); cache0.query(qry).getAll(); tx.commit(); } } catch (Exception e) { onException(ex, e); } } }, 2);
try (Transaction tx = node.transactions().txStart(PESSIMISTIC, REPEATABLE_READ)) { if (timeoutMode == TimeoutMode.TX) tx.timeout(TX_TIMEOUT);
@Override public void run() { IgniteEx node = grid(1); try { phaser.arriveAndAwaitAdvance(); try (Transaction tx = node.transactions().txStart(PESSIMISTIC, REPEATABLE_READ)) { tx.timeout(TX_TIMEOUT); IgniteCache<Integer, Integer> cache0 = node.cache(DEFAULT_CACHE_NAME); cache0.invokeAllAsync(F.asSet(1, 2, 3, 4, 5, 6), new EntryProcessor<Integer, Integer, Void>() { @Override public Void process(MutableEntry<Integer, Integer> entry, Object... arguments) throws EntryProcessorException { entry.setValue(entry.getValue() * 10); return null; } }); phaser.arrive(); tx.commit(); } } catch (Exception e) { onException(ex, e); } } }, 1));
/** * @throws Exception If failed. */ @Test public void testQueryInsertUpdateSameKeys() 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)); final 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("UPDATE Integer SET _val = (_key * 10)"); try (FieldsQueryCursor<List<?>> cur = cache0.query(qry)) { cur.getAll(); } tx.commit(); } assertEquals(10, cache.get(1)); assertEquals(20, cache.get(2)); assertEquals(30, cache.get(3)); }
tx.timeout(TX_TIMEOUT);
tx.timeout(TX_TIMEOUT);
tx.timeout(TX_TIMEOUT);
tx.timeout(TX_TIMEOUT);
tx.timeout(TX_TIMEOUT);
@Override public void run() { IgniteEx node = grid(0); try { try (Transaction tx = node.transactions().txStart(PESSIMISTIC, REPEATABLE_READ)) { tx.timeout(TX_TIMEOUT); IgniteCache<Object, Object> cache0 = node.cache(DEFAULT_CACHE_NAME); SqlFieldsQuery qry = new SqlFieldsQuery("INSERT INTO Integer (_key, _val) values (1,1),(2,2),(3,3)"); try (FieldsQueryCursor<List<?>> cur = cache0.query(qry)) { cur.getAll(); } awaitPhase(phaser, 2); qry = new SqlFieldsQuery("INSERT INTO Integer (_key, _val) values (4,4),(5,5),(6,6)"); try (FieldsQueryCursor<List<?>> cur = cache0.query(qry)) { cur.getAll(); } tx.commit(); } } catch (Exception e) { onException(ex, e); } } }, 1));
/** * @throws Exception If failed. */ @Test public void testQueryUpdateStaticCache() 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); cache.putAll(F.asMap(1, 1, 2, 2, 3, 3)); assertEquals(1, cache.get(1)); assertEquals(2, cache.get(2)); assertEquals(3, cache.get(3)); try (Transaction tx = updateNode.transactions().txStart(PESSIMISTIC, REPEATABLE_READ)) { tx.timeout(TX_TIMEOUT); SqlFieldsQuery qry = new SqlFieldsQuery("UPDATE Integer SET _val = (_key * 10)"); IgniteCache<Object, Object> cache0 = updateNode.cache(DEFAULT_CACHE_NAME); try (FieldsQueryCursor<List<?>> cur = cache0.query(qry)) { assertEquals(3L, cur.iterator().next().get(0)); } tx.commit(); } assertEquals(10, cache.get(1)); assertEquals(20, cache.get(2)); assertEquals(30, cache.get(3)); }