use of org.apache.ignite.IgniteTransactions in project ignite by apache.
the class CacheSerializableTransactionsTest method incrementTxMultiple.
/**
* @param nearCache If {@code true} near cache is enabled.
* @param store If {@code true} cache store is enabled.
* @param restart If {@code true} restarts one node.
* @throws Exception If failed.
*/
private void incrementTxMultiple(boolean nearCache, boolean store, final boolean restart) throws Exception {
final Ignite srv = ignite(1);
CacheConfiguration<Integer, Integer> ccfg = cacheConfiguration(PARTITIONED, FULL_SYNC, 1, store, false);
final List<Ignite> clients = clients();
final String cacheName = srv.createCache(ccfg).getName();
final AtomicBoolean stop = new AtomicBoolean();
try {
final List<IgniteCache<Integer, Integer>> caches = new ArrayList<>();
for (Ignite client : clients) {
if (nearCache)
caches.add(client.createNearCache(cacheName, new NearCacheConfiguration<Integer, Integer>()));
else
caches.add(client.<Integer, Integer>cache(cacheName));
}
IgniteInternalFuture<?> restartFut = restart ? restartFuture(stop, null) : null;
for (int i = 0; i < 20; i += 2) {
final AtomicInteger cntr = new AtomicInteger();
final Integer key1 = i;
final Integer key2 = i + 1;
final AtomicInteger threadIdx = new AtomicInteger();
final int THREADS = 10;
final CyclicBarrier barrier = new CyclicBarrier(THREADS);
final ConcurrentSkipListSet<Integer> vals1 = new ConcurrentSkipListSet<>();
final ConcurrentSkipListSet<Integer> vals2 = new ConcurrentSkipListSet<>();
GridTestUtils.runMultiThreadedAsync(new Callable<Void>() {
@Override
public Void call() throws Exception {
int idx = threadIdx.getAndIncrement() % caches.size();
IgniteCache<Integer, Integer> cache = caches.get(idx);
Ignite ignite = cache.unwrap(Ignite.class);
IgniteTransactions txs = ignite.transactions();
log.info("Started update thread: " + ignite.name());
barrier.await();
for (int i = 0; i < 1000; i++) {
try {
try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
Integer val1 = cache.get(key1);
Integer val2 = cache.get(key2);
Integer newVal1 = val1 == null ? 1 : val1 + 1;
Integer newVal2 = val2 == null ? 1 : val2 + 1;
cache.put(key1, newVal1);
cache.put(key2, newVal2);
tx.commit();
assertTrue(vals1.add(newVal1));
assertTrue(vals2.add(newVal2));
}
cntr.incrementAndGet();
} catch (TransactionOptimisticException ignore) {
// Retry.
} catch (IgniteException | CacheException e) {
assertTrue("Unexpected exception [err=" + e + ", cause=" + e.getCause() + ']', restart && X.hasCause(e, ClusterTopologyCheckedException.class));
}
}
return null;
}
}, THREADS, "update-thread").get();
log.info("Iteration [iter=" + i + ", val=" + cntr.get() + ']');
assertTrue(cntr.get() > 0);
checkValue(key1, cntr.get(), cacheName, restart);
checkValue(key2, cntr.get(), cacheName, restart);
}
stop.set(true);
if (restartFut != null)
restartFut.get();
} finally {
stop.set(true);
destroyCache(cacheName);
}
}
use of org.apache.ignite.IgniteTransactions in project ignite by apache.
the class CacheSerializableTransactionsTest method txConflictRead.
/**
* @param noVal If {@code true} there is no cache value when read in tx.
* @param needVer If {@code true} then gets entry, otherwise just value.
* @throws Exception If failed.
*/
private void txConflictRead(boolean noVal, boolean needVer) throws Exception {
Ignite ignite0 = ignite(0);
final IgniteTransactions txs = ignite0.transactions();
for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
logCacheInfo(ccfg);
try {
IgniteCache<Integer, Integer> cache = ignite0.createCache(ccfg);
List<Integer> keys = testKeys(cache);
for (Integer key : keys) {
log.info("Test key: " + key);
Integer expVal = null;
if (!noVal) {
expVal = -1;
cache.put(key, expVal);
}
try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
if (needVer) {
CacheEntry<Integer, Integer> val = cache.getEntry(key);
assertEquals(expVal, val == null ? null : val.getValue());
} else {
Integer val = cache.get(key);
assertEquals(expVal, val);
}
updateKey(cache, key, 1);
tx.commit();
fail();
} catch (TransactionOptimisticException e) {
log.info("Expected exception: " + e);
}
checkValue(key, 1, cache.getName());
try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
if (needVer) {
CacheEntry<Integer, Integer> val = cache.getEntry(key);
assertEquals((Integer) 1, val.getValue());
} else {
Object val = cache.get(key);
assertEquals(1, val);
}
tx.commit();
}
checkValue(key, 1, cache.getName());
}
} finally {
destroyCache(ccfg.getName());
}
}
}
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());
}
}
use of org.apache.ignite.IgniteTransactions in project ignite by apache.
the class CacheSerializableTransactionsTest method concurrentUpdateNoDeadlock.
/**
* @param updateNodes Nodes executing updates.
* @param threads Number of threads executing updates.
* @param get If {@code true} gets value in transaction.
* @param restart If {@code true} restarts one node.
* @param nonSer If {@code true} starts threads executing non-serializable transactions.
* @throws Exception If failed.
*/
private void concurrentUpdateNoDeadlock(final List<Ignite> updateNodes, int threads, final boolean get, final boolean restart, final boolean nonSer) throws Exception {
if (FAST)
return;
assert updateNodes.size() > 0;
final Ignite srv = ignite(1);
final String cacheName = srv.createCache(cacheConfiguration(PARTITIONED, FULL_SYNC, 1, false, false)).getName();
try {
final int KEYS = 100;
final AtomicBoolean finished = new AtomicBoolean();
IgniteInternalFuture<?> fut = restart ? restartFuture(finished, null) : null;
try {
for (int i = 0; i < 10; i++) {
log.info("Iteration: " + i);
final long stopTime = U.currentTimeMillis() + 10_000;
final AtomicInteger idx = new AtomicInteger();
IgniteInternalFuture<?> nonSerFut = null;
if (nonSer) {
nonSerFut = GridTestUtils.runMultiThreadedAsync(new Callable<Void>() {
@Override
public Void call() throws Exception {
int nodeIdx = idx.getAndIncrement() % updateNodes.size();
Ignite node = updateNodes.get(nodeIdx);
log.info("Non-serializable tx thread: " + node.name());
final IgniteCache<Integer, Integer> cache = node.cache(cacheName);
assertNotNull(cache);
final ThreadLocalRandom rnd = ThreadLocalRandom.current();
while (U.currentTimeMillis() < stopTime) {
final TreeMap<Integer, Integer> map = new TreeMap<>();
for (int i = 0; i < KEYS / 2; i++) map.put(rnd.nextInt(KEYS), rnd.nextInt());
TransactionConcurrency concurrency = rnd.nextBoolean() ? PESSIMISTIC : OPTIMISTIC;
doInTransaction(node, concurrency, REPEATABLE_READ, new Callable<Void>() {
@Override
public Void call() throws Exception {
cache.putAll(map);
return null;
}
});
}
return null;
}
}, 5, "non-ser-thread");
}
IgniteInternalFuture<?> updateFut = GridTestUtils.runMultiThreadedAsync(new Callable<Void>() {
@Override
public Void call() throws Exception {
int nodeIdx = idx.getAndIncrement() % updateNodes.size();
Ignite node = updateNodes.get(nodeIdx);
log.info("Tx thread: " + node.name());
final IgniteTransactions txs = node.transactions();
final IgniteCache<Integer, Integer> cache = node.cache(cacheName);
assertNotNull(cache);
final ThreadLocalRandom rnd = ThreadLocalRandom.current();
while (U.currentTimeMillis() < stopTime) {
final Map<Integer, Integer> map = new LinkedHashMap<>();
for (int i = 0; i < KEYS / 2; i++) map.put(rnd.nextInt(KEYS), rnd.nextInt());
try {
if (restart) {
doInTransaction(node, OPTIMISTIC, SERIALIZABLE, new Callable<Void>() {
@Override
public Void call() throws Exception {
if (get) {
for (Map.Entry<Integer, Integer> e : map.entrySet()) {
if (rnd.nextBoolean()) {
cache.get(e.getKey());
if (rnd.nextBoolean())
cache.put(e.getKey(), e.getValue());
} else
cache.put(e.getKey(), e.getValue());
}
} else
cache.putAll(map);
return null;
}
});
} else {
try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
if (get) {
for (Map.Entry<Integer, Integer> e : map.entrySet()) {
if (rnd.nextBoolean()) {
cache.get(e.getKey());
if (rnd.nextBoolean())
cache.put(e.getKey(), e.getValue());
} else
cache.put(e.getKey(), e.getValue());
}
} else
cache.putAll(map);
tx.commit();
}
}
} catch (TransactionOptimisticException ignore) {
// No-op.
} catch (Throwable e) {
log.error("Unexpected error: " + e, e);
throw e;
}
}
return null;
}
}, threads, "tx-thread");
updateFut.get(60, SECONDS);
if (nonSerFut != null)
nonSerFut.get(60, SECONDS);
IgniteCache<Integer, Integer> cache = srv.cache(cacheName);
for (int key = 0; key < KEYS; key++) {
Integer val = cache.get(key);
for (int node = 1; node < SRVS + CLIENTS; node++) assertEquals(val, ignite(node).cache(cache.getName()).get(key));
}
}
finished.set(true);
if (fut != null)
fut.get();
} finally {
finished.set(true);
}
} finally {
destroyCache(cacheName);
}
}
use of org.apache.ignite.IgniteTransactions in project ignite by apache.
the class CacheSerializableTransactionsTest method accountTx.
/**
* @param getAll If {@code true} uses getAll/putAll in transaction.
* @param nearCache If {@code true} near cache is enabled.
* @param nonSer If {@code true} starts threads executing non-serializable transactions.
* @param restart If {@code true} restarts one node.
* @throws Exception If failed.
*/
private void accountTx(final boolean getAll, final boolean nearCache, final boolean nonSer, final boolean restart) throws Exception {
final Ignite srv = ignite(1);
CacheConfiguration<Integer, Integer> ccfg = cacheConfiguration(PARTITIONED, FULL_SYNC, 1, false, false);
final String cacheName = srv.createCache(ccfg).getName();
try {
final List<Ignite> clients = clients();
final int ACCOUNTS = 100;
final int VAL_PER_ACCOUNT = 10_000;
IgniteCache<Integer, Account> srvCache = srv.cache(cacheName);
for (int i = 0; i < ACCOUNTS; i++) srvCache.put(i, new Account(VAL_PER_ACCOUNT));
final AtomicInteger idx = new AtomicInteger();
final int THREADS = 20;
final long testTime = 30_000;
final long stopTime = System.currentTimeMillis() + testTime;
IgniteInternalFuture<?> nonSerFut = null;
if (nonSer) {
nonSerFut = runMultiThreadedAsync(new Callable<Void>() {
@Override
public Void call() throws Exception {
int nodeIdx = idx.getAndIncrement() % clients.size();
Ignite node = clients.get(nodeIdx);
Thread.currentThread().setName("update-pessimistic-" + node.name());
log.info("Pessimistic tx thread: " + node.name());
final IgniteTransactions txs = node.transactions();
final IgniteCache<Integer, Account> cache = nearCache ? node.createNearCache(cacheName, new NearCacheConfiguration<Integer, Account>()) : node.<Integer, Account>cache(cacheName);
assertNotNull(cache);
ThreadLocalRandom rnd = ThreadLocalRandom.current();
while (U.currentTimeMillis() < stopTime) {
int id1 = rnd.nextInt(ACCOUNTS);
int id2 = rnd.nextInt(ACCOUNTS);
while (id2 == id1) id2 = rnd.nextInt(ACCOUNTS);
if (id1 > id2) {
int tmp = id1;
id1 = id2;
id2 = tmp;
}
try (Transaction tx = txs.txStart(PESSIMISTIC, REPEATABLE_READ)) {
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();
}
}
return null;
}
}, 10, "non-ser-thread");
}
final IgniteInternalFuture<?> fut = runMultiThreadedAsync(new Callable<Void>() {
@Override
public Void call() throws Exception {
int nodeIdx = idx.getAndIncrement() % clients.size();
Ignite node = clients.get(nodeIdx);
Thread.currentThread().setName("update-" + node.name());
log.info("Tx thread: " + node.name());
final IgniteTransactions txs = node.transactions();
final IgniteCache<Integer, Account> cache = nearCache ? node.createNearCache(cacheName, new NearCacheConfiguration<Integer, Account>()) : node.<Integer, Account>cache(cacheName);
assertNotNull(cache);
ThreadLocalRandom rnd = ThreadLocalRandom.current();
while (U.currentTimeMillis() < stopTime) {
int id1 = rnd.nextInt(ACCOUNTS);
int id2 = rnd.nextInt(ACCOUNTS);
while (id2 == id1) id2 = rnd.nextInt(ACCOUNTS);
try {
while (true) {
try {
try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
if (getAll) {
Map<Integer, Account> map = cache.getAll(F.asSet(id1, id2));
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);
}
map.put(id1, a1);
map.put(id2, a2);
cache.putAll(map);
} else {
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();
}
break;
} catch (TransactionOptimisticException ignore) {
// Retry.
} catch (IgniteException | CacheException e) {
assertTrue("Unexpected exception [err=" + e + ", cause=" + e.getCause() + ']', restart && X.hasCause(e, ClusterTopologyCheckedException.class));
}
}
} catch (Throwable e) {
log.error("Unexpected error: " + e, e);
throw e;
}
}
return null;
}
}, THREADS, "tx-thread");
IgniteInternalFuture<?> restartFut = restart ? restartFuture(null, fut) : null;
fut.get(testTime + 30_000);
if (nonSerFut != null)
nonSerFut.get();
if (restartFut != null)
restartFut.get();
int sum = 0;
for (int i = 0; i < ACCOUNTS; i++) {
Account a = srvCache.get(i);
assertNotNull(a);
assertTrue(a.value() >= 0);
log.info("Account: " + a.value());
sum += a.value();
}
assertEquals(ACCOUNTS * VAL_PER_ACCOUNT, sum);
for (int node = 0; node < SRVS + CLIENTS; node++) {
log.info("Verify node: " + node);
Ignite ignite = ignite(node);
IgniteCache<Integer, Account> cache = ignite.cache(cacheName);
sum = 0;
try (Transaction tx = ignite.transactions().txStart(OPTIMISTIC, SERIALIZABLE)) {
Map<Integer, Account> map = new HashMap<>();
for (int i = 0; i < ACCOUNTS; i++) {
Account a = cache.get(i);
assertNotNull(a);
map.put(i, a);
sum += a.value();
}
Account a1 = map.get(0);
Account a2 = map.get(1);
if (a1.value() > 0) {
a1 = new Account(a1.value() - 1);
a2 = new Account(a2.value() + 1);
map.put(0, a1);
map.put(1, a2);
}
cache.putAll(map);
tx.commit();
}
assertEquals(ACCOUNTS * VAL_PER_ACCOUNT, sum);
}
} finally {
destroyCache(cacheName);
}
}
Aggregations