use of org.apache.ignite.IgniteCache in project ignite by apache.
the class TxPessimisticDeadlockDetectionTest method doTestDeadlock.
/**
* @throws Exception If failed.
*/
private void doTestDeadlock(final int txCnt, final boolean loc, boolean lockPrimaryFirst, final boolean clientTx, final IgniteClosure<Integer, Object> transformer) throws Exception {
log.info(">>> Test deadlock [txCnt=" + txCnt + ", loc=" + loc + ", lockPrimaryFirst=" + lockPrimaryFirst + ", clientTx=" + clientTx + ", transformer=" + transformer.getClass().getName() + ']');
final AtomicInteger threadCnt = new AtomicInteger();
final CyclicBarrier barrier = new CyclicBarrier(txCnt);
final AtomicReference<TransactionDeadlockException> deadlockErr = new AtomicReference<>();
final List<List<Integer>> keySets = generateKeys(txCnt, loc, !lockPrimaryFirst);
final Set<Integer> involvedKeys = new GridConcurrentHashSet<>();
final Set<Integer> involvedLockedKeys = new GridConcurrentHashSet<>();
final Set<IgniteInternalTx> involvedTxs = new GridConcurrentHashSet<>();
IgniteInternalFuture<Long> fut = GridTestUtils.runMultiThreadedAsync(new Runnable() {
@Override
public void run() {
int threadNum = threadCnt.incrementAndGet();
Ignite ignite = loc ? ignite(0) : ignite(clientTx ? threadNum - 1 + txCnt : threadNum - 1);
IgniteCache<Object, Integer> cache = ignite.cache(CACHE_NAME);
List<Integer> keys = keySets.get(threadNum - 1);
int txTimeout = 500 + txCnt * 100;
try (Transaction tx = ignite.transactions().txStart(PESSIMISTIC, REPEATABLE_READ, txTimeout, 0)) {
involvedTxs.add(((TransactionProxyImpl) tx).tx());
Integer key = keys.get(0);
involvedKeys.add(key);
Object k;
log.info(">>> Performs put [node=" + ((IgniteKernal) ignite).localNode() + ", tx=" + tx + ", key=" + transformer.apply(key) + ']');
cache.put(transformer.apply(key), 0);
involvedLockedKeys.add(key);
barrier.await();
key = keys.get(1);
ClusterNode primaryNode = ((IgniteCacheProxy) cache).context().affinity().primaryByKey(key, NONE);
List<Integer> primaryKeys = primaryKeys(grid(primaryNode).cache(CACHE_NAME), 5, key + (100 * threadNum));
Map<Object, Integer> entries = new HashMap<>();
involvedKeys.add(key);
entries.put(transformer.apply(key), 0);
for (Integer i : primaryKeys) {
involvedKeys.add(i);
entries.put(transformer.apply(i), 1);
k = transformer.apply(i + 13);
involvedKeys.add(i + 13);
entries.put(k, 2);
}
log.info(">>> Performs put [node=" + ((IgniteKernal) ignite).localNode() + ", tx=" + tx + ", entries=" + entries + ']');
cache.putAll(entries);
tx.commit();
} catch (Throwable e) {
// At least one stack trace should contain TransactionDeadlockException.
if (hasCause(e, TransactionTimeoutException.class) && hasCause(e, TransactionDeadlockException.class)) {
if (deadlockErr.compareAndSet(null, cause(e, TransactionDeadlockException.class)))
U.error(log, "At least one stack trace should contain " + TransactionDeadlockException.class.getSimpleName(), e);
}
}
}
}, loc ? 2 : txCnt, "tx-thread");
try {
fut.get();
} catch (IgniteCheckedException e) {
U.error(null, "Unexpected exception", e);
fail();
}
U.sleep(1000);
TransactionDeadlockException deadlockE = deadlockErr.get();
assertNotNull(deadlockE);
boolean fail = false;
// Check transactions, futures and entry locks state.
for (int i = 0; i < NODES_CNT * 2; i++) {
Ignite ignite = ignite(i);
int cacheId = ((IgniteCacheProxy) ignite.cache(CACHE_NAME)).context().cacheId();
GridCacheSharedContext<Object, Object> cctx = ((IgniteKernal) ignite).context().cache().context();
IgniteTxManager txMgr = cctx.tm();
Collection<IgniteInternalTx> activeTxs = txMgr.activeTransactions();
for (IgniteInternalTx tx : activeTxs) {
Collection<IgniteTxEntry> entries = tx.allEntries();
for (IgniteTxEntry entry : entries) {
if (entry.cacheId() == cacheId) {
fail = true;
U.error(log, "Transaction still exists: " + "\n" + tx.xidVersion() + "\n" + tx.nearXidVersion() + "\n nodeId=" + cctx.localNodeId() + "\n tx=" + tx);
}
}
}
Collection<IgniteInternalFuture<?>> futs = txMgr.deadlockDetectionFutures();
assertTrue(futs.isEmpty());
GridCacheAdapter<Object, Integer> intCache = internalCache(i, CACHE_NAME);
GridCacheConcurrentMap map = intCache.map();
for (Integer key : involvedKeys) {
Object key0 = transformer.apply(key);
KeyCacheObject keyCacheObj = intCache.context().toCacheKeyObject(key0);
GridCacheMapEntry entry = map.getEntry(keyCacheObj);
if (entry != null)
assertNull("Entry still has locks " + entry, entry.mvccAllLocal());
}
}
if (fail)
fail("Some transactions still exist");
// Check deadlock report
String msg = deadlockE.getMessage();
for (IgniteInternalTx tx : involvedTxs) assertTrue(msg.contains("[txId=" + tx.xidVersion() + ", nodeId=" + tx.nodeId() + ", threadId=" + tx.threadId() + ']'));
for (Integer key : involvedKeys) {
if (involvedLockedKeys.contains(key))
assertTrue(msg.contains("[key=" + transformer.apply(key) + ", cache=" + CACHE_NAME + ']'));
else
assertFalse(msg.contains("[key=" + transformer.apply(key)));
}
}
use of org.apache.ignite.IgniteCache in project ignite by apache.
the class TxDeadlockDetectionNoHangsTest method doTest.
/**
* @param concurrency Concurrency.
* @throws IgniteCheckedException If failed.
*/
private void doTest(final TransactionConcurrency concurrency) throws IgniteCheckedException {
final AtomicBoolean stop = new AtomicBoolean();
IgniteInternalFuture<Long> restartFut = null;
try {
restartFut = GridTestUtils.runMultiThreadedAsync(new Runnable() {
@Override
public void run() {
while (!stop.get()) {
try {
U.sleep(500);
startGrid(NODES_CNT);
awaitPartitionMapExchange();
U.sleep(500);
stopGrid(NODES_CNT);
} catch (Exception ignored) {
// No-op.
}
}
}
}, 1, "restart-thread");
long stopTime = System.currentTimeMillis() + 2 * 60_000L;
for (int i = 0; System.currentTimeMillis() < stopTime; i++) {
boolean detectionEnabled = grid(0).context().cache().context().tm().deadlockDetectionEnabled();
log.info(">>> Iteration " + i + " (detection is " + (detectionEnabled ? "enabled" : "disabled") + ')');
final AtomicInteger threadCnt = new AtomicInteger();
IgniteInternalFuture<Long> fut = GridTestUtils.runMultiThreadedAsync(new Runnable() {
@Override
public void run() {
int threadNum = threadCnt.getAndIncrement();
Ignite ignite = ignite(threadNum % NODES_CNT);
IgniteCache<Integer, Integer> cache = ignite.cache(CACHE);
try (Transaction tx = ignite.transactions().txStart(concurrency, REPEATABLE_READ, 500, 0)) {
ThreadLocalRandom rnd = ThreadLocalRandom.current();
for (int i = 0; i < 50; i++) {
int key = rnd.nextInt(50);
if (log.isDebugEnabled()) {
log.info(">>> Performs put [node=" + ((IgniteKernal) ignite).localNode() + ", tx=" + tx + ", key=" + key + ']');
}
cache.put(key, 0);
}
tx.commit();
} catch (Exception e) {
log.info("Ignore error: " + e);
}
}
}, NODES_CNT * 3, "tx-thread");
fut.get();
}
} finally {
stop.set(true);
if (restartFut != null)
restartFut.get();
checkDetectionFutures();
}
}
use of org.apache.ignite.IgniteCache in project ignite by apache.
the class TxDeadlockDetectionTest method doTestFailedMessage.
/**
* @param failCls Failing message class.
* @throws Exception If failed.
*/
private void doTestFailedMessage(Class failCls) throws Exception {
try {
final int txCnt = 2;
final CyclicBarrier barrier = new CyclicBarrier(txCnt);
final AtomicInteger threadCnt = new AtomicInteger();
final AtomicBoolean deadlock = new AtomicBoolean();
final AtomicBoolean timeout = new AtomicBoolean();
TestCommunicationSpi.failCls = failCls;
IgniteInternalFuture<Long> fut = GridTestUtils.runMultiThreadedAsync(new Runnable() {
@Override
public void run() {
int num = threadCnt.getAndIncrement();
Ignite ignite = ignite(num);
IgniteCache<Object, Integer> cache = ignite.cache(CACHE);
try (Transaction tx = ignite.transactions().txStart(PESSIMISTIC, REPEATABLE_READ, num == 0 ? 500 : 1500, 0)) {
int key1 = primaryKey(ignite((num + 1) % txCnt).cache(CACHE));
log.info(">>> Performs put [node=" + ((IgniteKernal) ignite).localNode() + ", tx=" + tx + ", key=" + key1 + ']');
cache.put(new TestKey(key1), 1);
barrier.await();
int key2 = primaryKey(cache);
log.info(">>> Performs put [node=" + ((IgniteKernal) ignite).localNode() + ", tx=" + tx + ", key=" + key2 + ']');
cache.put(new TestKey(key2), 2);
tx.commit();
} catch (Exception e) {
timeout.compareAndSet(false, hasCause(e, TransactionTimeoutException.class));
deadlock.compareAndSet(false, hasCause(e, TransactionDeadlockException.class));
}
}
}, txCnt, "tx-thread");
fut.get();
assertFalse(deadlock.get());
assertTrue(timeout.get());
checkDetectionFuts();
} finally {
TestCommunicationSpi.failCls = null;
TestKey.failSer = false;
}
}
use of org.apache.ignite.IgniteCache in project ignite by apache.
the class IgnteCacheClientWriteBehindStoreNonCoalescingTest method updateKeys.
/**
* Update specified keys in async mode.
*
* @param cache Cache to use.
* @param keys Keys to update.
* @return IgniteFuture.
*/
private IgniteFuture<?> updateKeys(IgniteCache<Integer, Integer> cache, Set<Integer> keys) {
IgniteCache asyncCache = cache.withAsync();
// Using EntryProcessor.invokeAll to increment every value in place.
asyncCache.invokeAll(keys, new EntryProcessor<Integer, Integer, Object>() {
@Override
public Object process(MutableEntry<Integer, Integer> entry, Object... arguments) throws EntryProcessorException {
entry.setValue(entry.getValue() + 1);
return null;
}
});
return asyncCache.future();
}
use of org.apache.ignite.IgniteCache in project ignite by apache.
the class IgniteBinaryObjectFieldsQuerySelfTest method checkQuery.
/**
* @throws Exception If failed.
*/
private void checkQuery(CacheMode cacheMode, CacheAtomicityMode atomicity) throws Exception {
IgniteCache<Object, Object> cache = grid(GRID_CNT - 1).getOrCreateCache(cache(cacheMode, atomicity));
try {
populate(cache);
QueryCursor<Cache.Entry<Object, Object>> cur = cache.query(new SqlQuery("Person", "order " + "by id asc"));
List<Cache.Entry<Object, Object>> all = cur.getAll();
assertEquals(100, all.size());
for (int i = 0; i < 100; i++) {
Object person = all.get(i).getValue();
assertEquals(Integer.valueOf(i), U.field(person, "id"));
assertEquals("person-" + i, U.field(person, "name"));
assertEquals("person-last-" + i, U.field(person, "lastName"));
assertEquals((double) (i * 25), U.field(person, "salary"));
}
int max = 49;
// Check local scan query with keepBinary flag set.
ScanQuery<BinaryObject, BinaryObject> scanQry = new ScanQuery<>(new PersonKeyFilter(max));
QueryCursor<Cache.Entry<BinaryObject, BinaryObject>> curs = grid(GRID_CNT - 1).cache(DEFAULT_CACHE_NAME).withKeepBinary().query(scanQry);
List<Cache.Entry<BinaryObject, BinaryObject>> records = curs.getAll();
assertEquals(50, records.size());
for (Cache.Entry<BinaryObject, BinaryObject> entry : records) {
BinaryObject key = entry.getKey();
assertTrue(key.<Integer>field("id") <= max);
assertEquals(PERSON_KEY_CLS_NAME, key.deserialize().getClass().getName());
}
} finally {
grid(GRID_CNT - 1).cache(DEFAULT_CACHE_NAME).removeAll();
grid(GRID_CNT - 1).destroyCache(DEFAULT_CACHE_NAME);
}
}
Aggregations