use of org.apache.ignite.IgniteTransactions in project ignite by apache.
the class IgnitePersistentStoreTest method pojoStrategyTransactionTest.
/** */
@SuppressWarnings("unchecked")
private void pojoStrategyTransactionTest(Ignite ignite, TransactionConcurrency concurrency, TransactionIsolation isolation) {
LOGGER.info("-----------------------------------------------------------------------------------");
LOGGER.info("Running POJO transaction tests using " + concurrency + " concurrency and " + isolation + " isolation level");
LOGGER.info("-----------------------------------------------------------------------------------");
CacheStore productStore = CacheStoreHelper.createCacheStore("product", new ClassPathResource("org/apache/ignite/tests/persistence/pojo/product.xml"), CassandraHelper.getAdminDataSrc());
CacheStore orderStore = CacheStoreHelper.createCacheStore("order", new ClassPathResource("org/apache/ignite/tests/persistence/pojo/order.xml"), CassandraHelper.getAdminDataSrc());
Map<Long, Product> productsMap = TestsHelper.generateProductsMap(5);
Map<Long, Product> productsMap1;
Map<Long, ProductOrder> ordersMap = TestsHelper.generateOrdersMap(5);
Map<Long, ProductOrder> ordersMap1;
Product product = TestsHelper.generateRandomProduct(-1L);
ProductOrder order = TestsHelper.generateRandomOrder(-1L, -1L, new Date());
IgniteTransactions txs = ignite.transactions();
IgniteCache<Long, Product> productCache = ignite.getOrCreateCache(new CacheConfiguration<Long, Product>("product"));
IgniteCache<Long, ProductOrder> orderCache = ignite.getOrCreateCache(new CacheConfiguration<Long, ProductOrder>("order"));
LOGGER.info("Running POJO strategy write tests");
LOGGER.info("Running single operation write tests");
Transaction tx = txs.txStart(concurrency, isolation);
try {
productCache.put(product.getId(), product);
orderCache.put(order.getId(), order);
if (productStore.load(product.getId()) != null || orderStore.load(order.getId()) != null) {
throw new RuntimeException("Single write operation test failed. Transaction wasn't committed yet, but " + "objects were already persisted into Cassandra");
}
Map<Long, Product> products = (Map<Long, Product>) productStore.loadAll(productsMap.keySet());
Map<Long, ProductOrder> orders = (Map<Long, ProductOrder>) orderStore.loadAll(ordersMap.keySet());
if ((products != null && !products.isEmpty()) || (orders != null && !orders.isEmpty())) {
throw new RuntimeException("Single write operation test failed. Transaction wasn't committed yet, but " + "objects were already persisted into Cassandra");
}
tx.commit();
} finally {
U.closeQuiet(tx);
}
Product product1 = (Product) productStore.load(product.getId());
ProductOrder order1 = (ProductOrder) orderStore.load(order.getId());
if (product1 == null || order1 == null) {
throw new RuntimeException("Single write operation test failed. Transaction was committed, but " + "no objects were persisted into Cassandra");
}
if (!product.equals(product1) || !order.equals(order1)) {
throw new RuntimeException("Single write operation test failed. Transaction was committed, but " + "objects were incorrectly persisted/loaded to/from Cassandra");
}
LOGGER.info("Single operation write tests passed");
LOGGER.info("Running bulk operation write tests");
tx = txs.txStart(concurrency, isolation);
try {
productCache.putAll(productsMap);
orderCache.putAll(ordersMap);
productsMap1 = (Map<Long, Product>) productStore.loadAll(productsMap.keySet());
ordersMap1 = (Map<Long, ProductOrder>) orderStore.loadAll(ordersMap.keySet());
if ((productsMap1 != null && !productsMap1.isEmpty()) || (ordersMap1 != null && !ordersMap1.isEmpty())) {
throw new RuntimeException("Bulk write operation test failed. Transaction wasn't committed yet, but " + "objects were already persisted into Cassandra");
}
tx.commit();
} finally {
U.closeQuiet(tx);
}
productsMap1 = (Map<Long, Product>) productStore.loadAll(productsMap.keySet());
ordersMap1 = (Map<Long, ProductOrder>) orderStore.loadAll(ordersMap.keySet());
if (productsMap1 == null || productsMap1.isEmpty() || ordersMap1 == null || ordersMap1.isEmpty()) {
throw new RuntimeException("Bulk write operation test failed. Transaction was committed, but " + "no objects were persisted into Cassandra");
}
if (productsMap1.size() < productsMap.size() || ordersMap1.size() < ordersMap.size()) {
throw new RuntimeException("Bulk write operation test failed. There were committed less objects " + "into Cassandra than expected");
}
if (productsMap1.size() > productsMap.size() || ordersMap1.size() > ordersMap.size()) {
throw new RuntimeException("Bulk write operation test failed. There were committed more objects " + "into Cassandra than expected");
}
for (Map.Entry<Long, Product> entry : productsMap.entrySet()) {
product = productsMap1.get(entry.getKey());
if (!entry.getValue().equals(product)) {
throw new RuntimeException("Bulk write operation test failed. Transaction was committed, but " + "some objects were incorrectly persisted/loaded to/from Cassandra");
}
}
for (Map.Entry<Long, ProductOrder> entry : ordersMap.entrySet()) {
order = ordersMap1.get(entry.getKey());
if (!entry.getValue().equals(order)) {
throw new RuntimeException("Bulk write operation test failed. Transaction was committed, but " + "some objects were incorrectly persisted/loaded to/from Cassandra");
}
}
LOGGER.info("Bulk operation write tests passed");
LOGGER.info("POJO strategy write tests passed");
LOGGER.info("Running POJO strategy delete tests");
LOGGER.info("Running single delete tests");
tx = txs.txStart(concurrency, isolation);
try {
productCache.remove(-1L);
orderCache.remove(-1L);
if (productStore.load(-1L) == null || orderStore.load(-1L) == null) {
throw new RuntimeException("Single delete operation test failed. Transaction wasn't committed yet, but " + "objects were already deleted from Cassandra");
}
tx.commit();
} finally {
U.closeQuiet(tx);
}
if (productStore.load(-1L) != null || orderStore.load(-1L) != null) {
throw new RuntimeException("Single delete operation test failed. Transaction was committed, but " + "objects were not deleted from Cassandra");
}
LOGGER.info("Single delete tests passed");
LOGGER.info("Running bulk delete tests");
tx = txs.txStart(concurrency, isolation);
try {
productCache.removeAll(productsMap.keySet());
orderCache.removeAll(ordersMap.keySet());
productsMap1 = (Map<Long, Product>) productStore.loadAll(productsMap.keySet());
ordersMap1 = (Map<Long, ProductOrder>) orderStore.loadAll(ordersMap.keySet());
if (productsMap1.size() != productsMap.size() || ordersMap1.size() != ordersMap.size()) {
throw new RuntimeException("Bulk delete operation test failed. Transaction wasn't committed yet, but " + "objects were already deleted from Cassandra");
}
tx.commit();
} finally {
U.closeQuiet(tx);
}
productsMap1 = (Map<Long, Product>) productStore.loadAll(productsMap.keySet());
ordersMap1 = (Map<Long, ProductOrder>) orderStore.loadAll(ordersMap.keySet());
if ((productsMap1 != null && !productsMap1.isEmpty()) || (ordersMap1 != null && !ordersMap1.isEmpty())) {
throw new RuntimeException("Bulk delete operation test failed. Transaction was committed, but " + "objects were not deleted from Cassandra");
}
LOGGER.info("Bulk delete tests passed");
LOGGER.info("POJO strategy delete tests passed");
LOGGER.info("-----------------------------------------------------------------------------------");
LOGGER.info("Passed POJO transaction tests for " + concurrency + " concurrency and " + isolation + " isolation level");
LOGGER.info("-----------------------------------------------------------------------------------");
}
use of org.apache.ignite.IgniteTransactions in project ignite by apache.
the class IgniteClientReconnectMassiveShutdownTest method massiveServersShutdown.
/**
* @param stopType How tp stop node.
* @throws Exception If any error occurs.
*/
private void massiveServersShutdown(final StopType stopType) throws Exception {
clientMode = false;
startGridsMultiThreaded(GRID_CNT);
clientMode = true;
startGridsMultiThreaded(GRID_CNT, CLIENT_GRID_CNT);
final AtomicBoolean done = new AtomicBoolean();
// Starting a cache dynamically.
Ignite client = grid(GRID_CNT);
assertTrue(client.configuration().isClientMode());
final CacheConfiguration<String, Integer> cfg = new CacheConfiguration<>(DEFAULT_CACHE_NAME);
cfg.setCacheMode(PARTITIONED);
cfg.setAtomicityMode(TRANSACTIONAL);
cfg.setBackups(2);
IgniteCache<String, Integer> cache = client.getOrCreateCache(cfg);
assertNotNull(cache);
HashMap<String, Integer> put = new HashMap<>();
// Load some data.
for (int i = 0; i < 10_000; i++) put.put(String.valueOf(i), i);
cache.putAll(put);
// Preparing client nodes and starting cache operations from them.
final BlockingQueue<Integer> clientIdx = new LinkedBlockingQueue<>();
for (int i = GRID_CNT; i < GRID_CNT + CLIENT_GRID_CNT; i++) clientIdx.add(i);
final CountDownLatch latch = new CountDownLatch(CLIENT_GRID_CNT);
IgniteInternalFuture<?> clientsFut = multithreadedAsync(new Callable<Object>() {
@Override
public Object call() throws Exception {
try {
int idx = clientIdx.take();
Ignite ignite = grid(idx);
Thread.currentThread().setName("client-thread-" + ignite.name());
assertTrue(ignite.configuration().isClientMode());
IgniteCache<String, Integer> cache = ignite.getOrCreateCache(cfg);
assertNotNull(cache);
IgniteTransactions txs = ignite.transactions();
Random rand = new Random();
latch.countDown();
while (!done.get()) {
try (Transaction tx = txs.txStart(PESSIMISTIC, REPEATABLE_READ)) {
cache.put(String.valueOf(rand.nextInt(10_000)), rand.nextInt(50_000));
tx.commit();
} catch (ClusterTopologyException ex) {
ex.retryReadyFuture().get();
} catch (IgniteException | CacheException e) {
if (X.hasCause(e, IgniteClientDisconnectedException.class)) {
IgniteClientDisconnectedException cause = X.cause(e, IgniteClientDisconnectedException.class);
assert cause != null;
cause.reconnectFuture().get();
} else if (X.hasCause(e, ClusterTopologyException.class)) {
ClusterTopologyException cause = X.cause(e, ClusterTopologyException.class);
assert cause != null;
cause.retryReadyFuture().get();
} else
throw e;
}
}
return null;
} catch (Throwable e) {
log.error("Unexpected error: " + e, e);
throw e;
}
}
}, CLIENT_GRID_CNT, "client-thread");
try {
if (!latch.await(30, SECONDS)) {
log.warning("Failed to wait for for clients start.");
U.dumpThreads(log);
fail("Failed to wait for for clients start.");
}
// Killing a half of server nodes.
final int srvsToKill = GRID_CNT / 2;
final BlockingQueue<Integer> victims = new LinkedBlockingQueue<>();
for (int i = 0; i < srvsToKill; i++) victims.add(i);
final BlockingQueue<Integer> assassins = new LinkedBlockingQueue<>();
for (int i = srvsToKill; i < GRID_CNT; i++) assassins.add(i);
IgniteInternalFuture<?> srvsShutdownFut = multithreadedAsync(new Callable<Object>() {
@Override
public Object call() throws Exception {
Thread.sleep(5_000);
Ignite assassin = grid(assassins.take());
assertFalse(assassin.configuration().isClientMode());
Ignite victim = grid(victims.take());
assertFalse(victim.configuration().isClientMode());
log.info("Kill node [node=" + victim.name() + ", from=" + assassin.name() + ']');
switch(stopType) {
case CLOSE:
victim.close();
break;
case FAIL_EVENT:
UUID nodeId = victim.cluster().localNode().id();
assassin.configuration().getDiscoverySpi().failNode(nodeId, null);
break;
case SIMULATE_FAIL:
((TcpDiscoverySpi) victim.configuration().getDiscoverySpi()).simulateNodeFailure();
break;
default:
fail();
}
return null;
}
}, assassins.size(), "kill-thread");
srvsShutdownFut.get();
Thread.sleep(15_000);
done.set(true);
clientsFut.get();
awaitPartitionMapExchange();
for (int k = 0; k < 10_000; k++) {
String key = String.valueOf(k);
Object val = cache.get(key);
for (int i = srvsToKill; i < GRID_CNT; i++) assertEquals(val, ignite(i).cache(DEFAULT_CACHE_NAME).get(key));
}
} finally {
done.set(true);
}
}
use of org.apache.ignite.IgniteTransactions in project ignite by apache.
the class IgniteClientReconnectCacheTest method reconnectTransactionInProgress1.
/**
* @param client Client.
* @param txConcurrency Transaction concurrency mode.
* @param cache Cache.
* @throws Exception If failed.
*/
private void reconnectTransactionInProgress1(IgniteEx client, final TransactionConcurrency txConcurrency, final IgniteCache<Object, Object> cache) throws Exception {
Ignite srv = clientRouter(client);
final TestTcpDiscoverySpi clientSpi = spi(client);
final TestTcpDiscoverySpi srvSpi = spi(srv);
final CountDownLatch disconnectLatch = new CountDownLatch(1);
final CountDownLatch reconnectLatch = new CountDownLatch(1);
log.info("Block reconnect.");
clientSpi.writeLatch = new CountDownLatch(1);
client.events().localListen(new IgnitePredicate<Event>() {
@Override
public boolean apply(Event evt) {
if (evt.type() == EVT_CLIENT_NODE_DISCONNECTED) {
info("Disconnected: " + evt);
disconnectLatch.countDown();
} else if (evt.type() == EVT_CLIENT_NODE_RECONNECTED) {
info("Reconnected: " + evt);
reconnectLatch.countDown();
}
return true;
}
}, EVT_CLIENT_NODE_DISCONNECTED, EVT_CLIENT_NODE_RECONNECTED);
final IgniteTransactions txs = client.transactions();
final CountDownLatch afterPut1 = new CountDownLatch(1);
final CountDownLatch afterPut2 = new CountDownLatch(1);
final CountDownLatch putFailed = new CountDownLatch(1);
IgniteInternalFuture<Boolean> fut = GridTestUtils.runAsync(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
try {
log.info("Start tx1: " + txConcurrency);
try (Transaction tx = txs.txStart(txConcurrency, REPEATABLE_READ)) {
cache.put(1, 1);
afterPut1.countDown();
afterPut2.await();
cache.put(2, 2);
fail();
} catch (CacheException e) {
log.info("Expected exception: " + e);
putFailed.countDown();
IgniteClientDisconnectedException e0 = (IgniteClientDisconnectedException) e.getCause();
e0.reconnectFuture().get();
}
log.info("Start tx2: " + txConcurrency);
try (Transaction tx = txs.txStart(txConcurrency, REPEATABLE_READ)) {
cache.put(1, 1);
cache.put(2, 2);
tx.commit();
}
assertEquals(1, cache.get(1));
assertEquals(2, cache.get(2));
try (Transaction tx = txs.txStart(txConcurrency, REPEATABLE_READ)) {
cache.put(3, 3);
cache.put(4, 4);
tx.commit();
}
assertEquals(1, cache.get(1));
assertEquals(2, cache.get(2));
assertEquals(3, cache.get(3));
assertEquals(4, cache.get(4));
cache.removeAll();
return true;
} catch (AssertionFailedError e) {
throw e;
} catch (Throwable e) {
log.error("Unexpected error", e);
fail("Unexpected error: " + e);
return false;
}
}
});
assertTrue(afterPut1.await(5000, MILLISECONDS));
assertNotDone(fut);
srvSpi.failNode(client.localNode().id(), null);
waitReconnectEvent(disconnectLatch);
afterPut2.countDown();
assertTrue(putFailed.await(5000, MILLISECONDS));
clientSpi.writeLatch.countDown();
waitReconnectEvent(reconnectLatch);
assertTrue(fut.get());
}
use of org.apache.ignite.IgniteTransactions in project ignite by apache.
the class CacheSerializableTransactionsTest method testCrossCacheTx.
/**
* @throws Exception If failed.
*/
public void testCrossCacheTx() throws Exception {
Ignite ignite0 = ignite(0);
final String CACHE1 = "cache1";
final String CACHE2 = "cache2";
try {
CacheConfiguration<Integer, Integer> ccfg1 = cacheConfiguration(PARTITIONED, FULL_SYNC, 1, false, false);
ccfg1.setName(CACHE1);
ignite0.createCache(ccfg1);
CacheConfiguration<Integer, Integer> ccfg2 = cacheConfiguration(PARTITIONED, FULL_SYNC, 1, false, false);
ccfg2.setName(CACHE2);
ignite0.createCache(ccfg2);
Integer newVal = 0;
List<Integer> keys = testKeys(ignite0.<Integer, Integer>cache(CACHE1));
for (Ignite ignite : G.allGrids()) {
log.info("Test node: " + ignite.name());
IgniteCache<Integer, Integer> cache1 = ignite.cache(CACHE1);
IgniteCache<Integer, Integer> cache2 = ignite.cache(CACHE2);
IgniteTransactions txs = ignite.transactions();
for (Integer key : keys) {
try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
cache1.put(key, newVal);
cache2.put(key, newVal);
tx.commit();
}
checkValue(key, newVal, CACHE1);
checkValue(key, newVal, CACHE2);
try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
Object val1 = cache1.get(key);
Object val2 = cache2.get(key);
assertEquals(newVal, val1);
assertEquals(newVal, val2);
tx.commit();
}
try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
cache1.put(key, newVal + 1);
cache2.put(key, newVal + 1);
tx.rollback();
}
checkValue(key, newVal, CACHE1);
checkValue(key, newVal, CACHE2);
try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
Object val1 = cache1.get(key);
Object val2 = cache2.get(key);
assertEquals(newVal, val1);
assertEquals(newVal, val2);
cache1.put(key, newVal + 1);
cache2.put(key, newVal + 1);
tx.commit();
}
newVal++;
checkValue(key, newVal, CACHE1);
checkValue(key, newVal, CACHE2);
try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
cache1.put(key, newVal);
cache2.put(-key, newVal);
tx.commit();
}
checkValue(key, newVal, CACHE1);
checkValue(-key, null, CACHE1);
checkValue(key, newVal, CACHE2);
checkValue(-key, newVal, CACHE2);
}
newVal++;
Integer key1 = primaryKey(ignite(0).cache(CACHE1));
Integer key2 = primaryKey(ignite(1).cache(CACHE1));
try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
cache1.put(key1, newVal);
cache1.put(key2, newVal);
cache2.put(key1, newVal);
cache2.put(key2, newVal);
tx.commit();
}
checkValue(key1, newVal, CACHE1);
checkValue(key2, newVal, CACHE1);
checkValue(key1, newVal, CACHE2);
checkValue(key2, newVal, CACHE2);
CountDownLatch latch = new CountDownLatch(1);
IgniteInternalFuture<?> fut = lockKey(latch, cache1, key1);
try {
try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
cache1.put(key1, newVal + 1);
cache2.put(key1, newVal + 1);
tx.commit();
}
fail();
} catch (TransactionOptimisticException e) {
log.info("Expected exception: " + e);
}
latch.countDown();
fut.get();
checkValue(key1, 1, CACHE1);
checkValue(key1, newVal, CACHE2);
try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
cache1.put(key1, newVal + 1);
cache2.put(key1, newVal + 1);
tx.commit();
}
newVal++;
cache1.put(key2, newVal);
cache2.put(key2, newVal);
checkValue(key1, newVal, CACHE1);
checkValue(key1, newVal, CACHE2);
latch = new CountDownLatch(1);
fut = lockKey(latch, cache1, key1);
try {
try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
cache1.put(key1, newVal + 1);
cache2.put(key2, newVal + 1);
tx.commit();
}
fail();
} catch (TransactionOptimisticException e) {
log.info("Expected exception: " + e);
}
latch.countDown();
fut.get();
checkValue(key1, 1, CACHE1);
checkValue(key2, newVal, CACHE2);
try {
try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
Object val1 = cache1.get(key1);
Object val2 = cache2.get(key2);
assertEquals(1, val1);
assertEquals(newVal, val2);
updateKey(cache2, key2, 1);
cache1.put(key1, newVal + 1);
cache2.put(key2, newVal + 1);
tx.commit();
}
fail();
} catch (TransactionOptimisticException e) {
log.info("Expected exception: " + e);
}
checkValue(key1, 1, CACHE1);
checkValue(key2, 1, CACHE2);
try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
Object val1 = cache1.get(key1);
Object val2 = cache2.get(key2);
assertEquals(1, val1);
assertEquals(1, val2);
cache1.put(key1, newVal + 1);
cache2.put(key2, newVal + 1);
tx.commit();
}
newVal++;
checkValue(key1, newVal, CACHE1);
checkValue(key2, newVal, CACHE2);
try {
try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
Object val1 = cache1.get(key1);
Object val2 = cache2.get(key2);
assertEquals(newVal, val1);
assertEquals(newVal, val2);
updateKey(cache2, key2, newVal);
tx.commit();
}
fail();
} catch (TransactionOptimisticException e) {
log.info("Expected exception: " + e);
}
try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
Object val1 = cache1.get(key1);
Object val2 = cache2.get(key2);
assertEquals(newVal, val1);
assertEquals(newVal, val2);
tx.commit();
}
}
} finally {
destroyCache(CACHE1);
destroyCache(CACHE2);
}
}
use of org.apache.ignite.IgniteTransactions in project ignite by apache.
the class CacheSerializableTransactionsTest method testReadWriteAccountTx.
/**
* @throws Exception If failed.
*/
public void testReadWriteAccountTx() throws Exception {
final CacheConfiguration<Integer, Integer> ccfg = cacheConfiguration(PARTITIONED, FULL_SYNC, 1, false, false);
ignite(0).createCache(ccfg);
try {
final int ACCOUNTS = 50;
final int VAL_PER_ACCOUNT = 1000;
IgniteCache<Integer, Account> cache0 = ignite(0).cache(ccfg.getName());
final Set<Integer> keys = new HashSet<>();
for (int i = 0; i < ACCOUNTS; i++) {
cache0.put(i, new Account(VAL_PER_ACCOUNT));
keys.add(i);
}
final List<Ignite> clients = clients();
final AtomicBoolean stop = new AtomicBoolean();
final AtomicInteger idx = new AtomicInteger();
IgniteInternalFuture<?> readFut = GridTestUtils.runMultiThreadedAsync(new Callable<Void>() {
@Override
public Void call() throws Exception {
try {
int threadIdx = idx.getAndIncrement();
int nodeIdx = threadIdx % (SRVS + CLIENTS);
Ignite node = ignite(nodeIdx);
IgniteCache<Integer, Account> cache = node.cache(ccfg.getName());
IgniteTransactions txs = node.transactions();
Integer putKey = ACCOUNTS + threadIdx;
while (!stop.get()) {
int sum;
while (true) {
sum = 0;
try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
Map<Integer, Account> data = cache.getAll(keys);
for (int i = 0; i < ACCOUNTS; i++) {
Account account = data.get(i);
assertNotNull(account);
sum += account.value();
}
if (ThreadLocalRandom.current().nextBoolean())
cache.put(putKey, new Account(sum));
tx.commit();
} catch (TransactionOptimisticException ignored) {
continue;
}
break;
}
assertEquals(ACCOUNTS * VAL_PER_ACCOUNT, sum);
}
return null;
} catch (Throwable e) {
stop.set(true);
log.error("Unexpected error: " + e);
throw e;
}
}
}, (SRVS + CLIENTS) * 2, "update-thread");
IgniteInternalFuture<?> updateFut = GridTestUtils.runMultiThreadedAsync(new Callable<Void>() {
@Override
public Void call() throws Exception {
try {
int nodeIdx = idx.getAndIncrement() % clients.size();
Ignite node = clients.get(nodeIdx);
IgniteCache<Integer, Account> cache = node.cache(ccfg.getName());
IgniteTransactions txs = node.transactions();
ThreadLocalRandom rnd = ThreadLocalRandom.current();
while (!stop.get()) {
int id1 = rnd.nextInt(ACCOUNTS);
int id2 = rnd.nextInt(ACCOUNTS);
while (id2 == id1) id2 = rnd.nextInt(ACCOUNTS);
while (true) {
try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
Account a1 = cache.get(id1);
Account a2 = cache.get(id2);
assertNotNull(a1);
assertNotNull(a2);
if (a1.value() > 0) {
a1 = new Account(a1.value() - 1);
a2 = new Account(a2.value() + 1);
}
cache.put(id1, a1);
cache.put(id2, a2);
tx.commit();
} catch (TransactionOptimisticException ignored) {
continue;
}
break;
}
}
return null;
} catch (Throwable e) {
stop.set(true);
log.error("Unexpected error: " + e);
throw e;
}
}
}, 2, "update-thread");
try {
U.sleep(15_000);
} finally {
stop.set(true);
}
readFut.get();
updateFut.get();
int sum = 0;
for (int i = 0; i < ACCOUNTS; i++) {
Account a = cache0.get(i);
assertNotNull(a);
assertTrue(a.value() >= 0);
log.info("Account: " + a.value());
sum += a.value();
}
assertEquals(ACCOUNTS * VAL_PER_ACCOUNT, sum);
} finally {
ignite(0).destroyCache(ccfg.getName());
}
}
Aggregations