use of org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL in project ignite by apache.
the class AbstractReadRepairTest method checkEvent.
/**
*/
protected void checkEvent(ReadRepairData data, IgniteIrreparableConsistencyViolationException e) {
Map<Object, Map<ClusterNode, CacheConsistencyViolationEvent.EntryInfo>> evtEntries = new HashMap<>();
Map<Object, Object> evtFixed = new HashMap<>();
Map<Integer, InconsistentMapping> inconsistent = data.data.entrySet().stream().filter(entry -> !entry.getValue().consistent).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
while (!evtEntries.keySet().equals(inconsistent.keySet())) {
if (!evtDeq.isEmpty()) {
CacheConsistencyViolationEvent evt = evtDeq.remove();
assertEquals(atomicityMode() == TRANSACTIONAL ? data.strategy : ReadRepairStrategy.CHECK_ONLY, evt.getStrategy());
// Optimistic and read committed transactions produce per key fixes.
evtEntries.putAll(evt.getEntries());
evtFixed.putAll(evt.getFixedEntries());
}
}
for (Map.Entry<Integer, InconsistentMapping> mapping : inconsistent.entrySet()) {
Integer key = mapping.getKey();
Integer fixed = mapping.getValue().fixed;
Integer primary = mapping.getValue().primary;
boolean repairable = mapping.getValue().repairable;
if (!repairable)
assertNotNull(e);
if (e == null) {
assertTrue(repairable);
assertTrue(evtFixed.containsKey(key));
assertEquals(fixed, evtFixed.get(key));
} else // Repairable but not repaired (because of irreparable entry at the same tx) entries.
if (e.irreparableKeys().contains(key) || (e.repairableKeys() != null && e.repairableKeys().contains(key)))
assertFalse(evtFixed.containsKey(key));
Map<ClusterNode, CacheConsistencyViolationEvent.EntryInfo> evtEntryInfos = evtEntries.get(key);
if (evtEntryInfos != null)
for (Map.Entry<ClusterNode, CacheConsistencyViolationEvent.EntryInfo> evtEntryInfo : evtEntryInfos.entrySet()) {
ClusterNode node = evtEntryInfo.getKey();
CacheConsistencyViolationEvent.EntryInfo info = evtEntryInfo.getValue();
if (info.isCorrect())
assertEquals(fixed, info.getValue());
if (info.isPrimary()) {
assertEquals(primary, info.getValue());
assertEquals(node, primaryNode(key, DEFAULT_CACHE_NAME).cluster().localNode());
}
}
}
int expectedFixedCnt = inconsistent.size() - (e != null ? (e.repairableKeys() != null ? e.repairableKeys().size() : 0) + e.irreparableKeys().size() : 0);
assertEquals(expectedFixedCnt, evtFixed.size());
assertTrue(evtDeq.isEmpty());
}
use of org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL in project ignite by apache.
the class CacheBlockOnReadAbstractTest method testStopBaselineTransactionalReplicated.
/**
* @throws Exception If failed.
*/
@Params(baseline = 9, atomicityMode = TRANSACTIONAL, cacheMode = REPLICATED)
@Test
public void testStopBaselineTransactionalReplicated() throws Exception {
AtomicInteger cntDownCntr = new AtomicInteger(0);
doTest(asMessagePredicate(discoEvt -> discoEvt.type() == EventType.EVT_NODE_LEFT), () -> {
IgniteEx node = baseline.get(baseline.size() - cntDownCntr.get() - 1);
TestRecordingCommunicationSpi.spi(node).stopBlock();
cntDownCntr.incrementAndGet();
for (int i = 0; i < cntDownCntr.get(); i++) // This node and previously stopped nodes as well.
cntFinishedReadOperations.countDown();
stopGrid(node.name());
});
}
use of org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL in project ignite by apache.
the class GridCommandHandlerTest method testKillHangingRemoteTransactions.
/**
* Simulate uncommitted backup transactions and test rolling back using utility.
*/
@Test
public void testKillHangingRemoteTransactions() throws Exception {
final int cnt = 3;
startGridsMultiThreaded(cnt);
Ignite[] clients = new Ignite[] { startGrid("client1"), startGrid("client2"), startGrid("client3"), startGrid("client4") };
clients[0].getOrCreateCache(new CacheConfiguration<>(DEFAULT_CACHE_NAME).setBackups(2).setAtomicityMode(TRANSACTIONAL).setWriteSynchronizationMode(FULL_SYNC).setAffinity(new RendezvousAffinityFunction(false, 64)));
awaitPartitionMapExchange();
for (Ignite client : clients) {
assertTrue(client.configuration().isClientMode());
assertNotNull(client.cache(DEFAULT_CACHE_NAME));
}
LongAdder progress = new LongAdder();
AtomicInteger idx = new AtomicInteger();
int tc = clients.length;
CountDownLatch lockLatch = new CountDownLatch(1);
CountDownLatch commitLatch = new CountDownLatch(1);
Ignite prim = primaryNode(0L, DEFAULT_CACHE_NAME);
TestRecordingCommunicationSpi primSpi = TestRecordingCommunicationSpi.spi(prim);
primSpi.blockMessages(new IgniteBiPredicate<ClusterNode, Message>() {
@Override
public boolean apply(ClusterNode node, Message message) {
return message instanceof GridDhtTxFinishRequest;
}
});
Set<IgniteUuid> xidSet = new GridConcurrentHashSet<>();
IgniteInternalFuture<?> fut = multithreadedAsync(new Runnable() {
@Override
public void run() {
int id = idx.getAndIncrement();
Ignite client = clients[id];
try (Transaction tx = client.transactions().txStart(PESSIMISTIC, READ_COMMITTED, 0, 1)) {
xidSet.add(tx.xid());
IgniteCache<Long, Long> cache = client.cache(DEFAULT_CACHE_NAME);
if (id != 0)
U.awaitQuiet(lockLatch);
cache.invoke(0L, new IncrementClosure(), null);
if (id == 0) {
lockLatch.countDown();
U.awaitQuiet(commitLatch);
// Wait until candidates will enqueue.
doSleep(500);
}
tx.commit();
} catch (Exception e) {
assertTrue(X.hasCause(e, TransactionTimeoutException.class));
}
progress.increment();
}
}, tc, "invoke-thread");
U.awaitQuiet(lockLatch);
commitLatch.countDown();
primSpi.waitForBlocked(clients.length);
// Unblock only finish messages from clients from 2 to 4.
primSpi.stopBlock(true, blockedMsg -> {
GridIoMessage iom = blockedMsg.ioMessage();
Message m = iom.message();
if (m instanceof GridDhtTxFinishRequest) {
GridDhtTxFinishRequest r = (GridDhtTxFinishRequest) m;
return !r.nearNodeId().equals(clients[0].cluster().localNode().id());
}
return true;
});
// Wait until queue is stable
for (Ignite ignite : G.allGrids()) {
if (ignite.configuration().isClientMode())
continue;
Collection<IgniteInternalTx> txs = ((IgniteEx) ignite).context().cache().context().tm().activeTransactions();
waitForCondition(new GridAbsPredicate() {
@Override
public boolean apply() {
for (IgniteInternalTx tx : txs) if (!tx.local()) {
IgniteTxEntry entry = tx.writeEntries().iterator().next();
GridCacheEntryEx cached = entry.cached();
Collection<GridCacheMvccCandidate> candidates = cached.remoteMvccSnapshot();
if (candidates.size() != clients.length)
return false;
}
return true;
}
}, 10_000);
}
CommandHandler h = new CommandHandler();
// Check listing.
validate(h, map -> {
for (int i = 0; i < cnt; i++) {
IgniteEx grid = grid(i);
// Skip primary.
if (grid.localNode().id().equals(prim.cluster().localNode().id()))
continue;
VisorTxTaskResult res = map.get(grid.localNode());
List<VisorTxInfo> infos = res.getInfos().stream().filter(info -> xidSet.contains(info.getNearXid())).collect(Collectors.toList());
// Validate queue length on backups.
assertEquals(clients.length, infos.size());
}
}, "--tx");
// Check kill.
validate(h, map -> {
// No-op.
}, "--tx", "--kill");
// Wait for all remote txs to finish.
for (Ignite ignite : G.allGrids()) {
if (ignite.configuration().isClientMode())
continue;
Collection<IgniteInternalTx> txs = ((IgniteEx) ignite).context().cache().context().tm().activeTransactions();
for (IgniteInternalTx tx : txs) if (!tx.local())
tx.finishFuture().get();
}
// Unblock finish message from client1.
primSpi.stopBlock(true);
fut.get();
Long cur = (Long) clients[0].cache(DEFAULT_CACHE_NAME).get(0L);
assertEquals(tc - 1, cur.longValue());
checkUserFutures();
}
use of org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL in project ignite by apache.
the class CacheBlockOnReadAbstractTest method testUpdateBaselineTopologyTransactionalReplicated.
/**
* @throws Exception If failed.
*/
@Params(timeout = 5000L, atomicityMode = TRANSACTIONAL, cacheMode = REPLICATED)
@Test
public void testUpdateBaselineTopologyTransactionalReplicated() throws Exception {
doTest(asMessagePredicate(discoEvt -> {
if (discoEvt instanceof DiscoveryCustomEvent) {
DiscoveryCustomEvent discoCustomEvt = (DiscoveryCustomEvent) discoEvt;
DiscoveryCustomMessage customMsg = discoCustomEvt.customMessage();
return customMsg instanceof ChangeGlobalStateMessage;
}
return false;
}), () -> {
startNodesInClientMode(false);
IgniteEx ignite = startGrid(UUID.randomUUID().toString());
baseline.get(0).cluster().setBaselineTopology(baseline.get(0).context().discovery().topologyVersion());
baseline.add(ignite);
});
}
use of org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL in project ignite by apache.
the class CacheBlockOnReadAbstractTest method testRestartBaselineTransactionalReplicated.
/**
* @throws Exception If failed.
*/
@Params(baseline = 4, atomicityMode = TRANSACTIONAL, cacheMode = REPLICATED)
@Test
public void testRestartBaselineTransactionalReplicated() throws Exception {
doTest(asMessagePredicate(discoEvt -> discoEvt.type() == EventType.EVT_NODE_JOINED), () -> {
IgniteEx node = baseline.get(baseline.size() - 1);
TestRecordingCommunicationSpi.spi(node).stopBlock();
stopGrid(node.name());
for (int i = 0; i < baselineServersCount() - 2; i++) cntFinishedReadOperations.countDown();
startGrid(node.name());
});
}
Aggregations