use of org.apache.ignite.spi.systemview.view.TransactionView in project ignite by apache.
the class FunctionalTest method testTransactionsWithLabel.
/**
* Test transactions with label.
*/
@Test
public void testTransactionsWithLabel() throws Exception {
try (IgniteEx ignite = (IgniteEx) Ignition.start(Config.getServerConfiguration());
IgniteClient client = Ignition.startClient(getClientConfiguration())) {
ClientCache<Integer, String> cache = client.createCache(new ClientCacheConfiguration().setName("cache").setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL));
SystemView<TransactionView> txsView = ignite.context().systemView().view(TXS_MON_LIST);
cache.put(0, "value1");
try (ClientTransaction tx = client.transactions().withLabel("label").txStart()) {
cache.put(0, "value2");
assertEquals(1, F.size(txsView.iterator()));
TransactionView txv = txsView.iterator().next();
assertEquals("label", txv.label());
assertEquals("value2", cache.get(0));
}
assertEquals("value1", cache.get(0));
try (ClientTransaction tx = client.transactions().withLabel("label1").withLabel("label2").txStart()) {
cache.put(0, "value2");
assertEquals(1, F.size(txsView.iterator()));
TransactionView txv = txsView.iterator().next();
assertEquals("label2", txv.label());
tx.commit();
}
assertEquals("value2", cache.get(0));
// Test concurrent with label and without label transactions.
try (ClientTransaction tx = client.transactions().withLabel("label").txStart(PESSIMISTIC, READ_COMMITTED)) {
CyclicBarrier barrier = new CyclicBarrier(2);
cache.put(0, "value3");
IgniteInternalFuture<?> fut = GridTestUtils.runAsync(() -> {
try (ClientTransaction tx1 = client.transactions().txStart(PESSIMISTIC, READ_COMMITTED)) {
cache.put(1, "value3");
barrier.await();
assertEquals("value2", cache.get(0));
barrier.await();
} catch (InterruptedException | BrokenBarrierException ignore) {
// No-op.
}
});
barrier.await();
assertNull(cache.get(1));
assertEquals(1, F.size(txsView.iterator(), txv -> txv.label() == null));
assertEquals(1, F.size(txsView.iterator(), txv -> "label".equals(txv.label())));
barrier.await();
fut.get();
}
// Test nested transactions is not possible.
try (ClientTransaction tx = client.transactions().withLabel("label1").txStart()) {
try (ClientTransaction tx1 = client.transactions().txStart()) {
fail();
} catch (ClientException expected) {
// No-op.
}
try (ClientTransaction tx1 = client.transactions().withLabel("label2").txStart()) {
fail();
} catch (ClientException expected) {
// No-op.
}
}
}
}
use of org.apache.ignite.spi.systemview.view.TransactionView in project ignite by apache.
the class IgniteTxManager method start0.
/**
* {@inheritDoc}
*/
@Override
protected void start0() throws IgniteCheckedException {
txHnd = new IgniteTxHandler(cctx);
deferredAckMsgSnd = new GridDeferredAckMessageSender<GridCacheVersion>(cctx.time(), cctx.kernalContext().closure()) {
@Override
public int getTimeout() {
return DEFERRED_ONE_PHASE_COMMIT_ACK_REQUEST_TIMEOUT;
}
@Override
public int getBufferSize() {
return DEFERRED_ONE_PHASE_COMMIT_ACK_REQUEST_BUFFER_SIZE;
}
@Override
public void finish(UUID nodeId, Collection<GridCacheVersion> vers) {
GridDhtTxOnePhaseCommitAckRequest ackReq = new GridDhtTxOnePhaseCommitAckRequest(vers);
cctx.kernalContext().gateway().readLock();
try {
cctx.io().send(nodeId, ackReq, GridIoPolicy.SYSTEM_POOL);
} catch (ClusterTopologyCheckedException ignored) {
if (log.isDebugEnabled())
log.debug("Failed to send one phase commit ack to backup node because it left grid: " + nodeId);
} catch (IgniteCheckedException e) {
log.error("Failed to send one phase commit ack to backup node [backup=" + nodeId + ']', e);
} finally {
cctx.kernalContext().gateway().readUnlock();
}
}
};
cctx.gridEvents().addDiscoveryEventListener(new TransactionRecoveryListener(), EVT_NODE_FAILED, EVT_NODE_LEFT);
cctx.gridEvents().addDiscoveryEventListener(new DiscoveryEventListener() {
@Override
public void onEvent(DiscoveryEvent evt, DiscoCache discoCache) {
if (evt.type() == EVT_NODE_FAILED || evt.type() == EVT_NODE_LEFT) {
UUID nodeId = evt.eventNode().id();
for (TxDeadlockFuture fut : deadlockDetectFuts.values()) fut.onNodeLeft(nodeId);
for (Map.Entry<GridCacheVersion, Object> entry : completedVersHashMap.entrySet()) {
Object obj = entry.getValue();
if (obj instanceof GridCacheReturnCompletableWrapper && nodeId.equals(((GridCacheReturnCompletableWrapper) obj).nodeId()))
removeTxReturn(entry.getKey());
}
}
suspendResumeForPessimisticSupported = IgniteFeatures.allNodesSupports(cctx.discovery().remoteNodes(), IgniteFeatures.SUSPEND_RESUME_PESSIMISTIC_TX);
}
}, EVT_NODE_FAILED, EVT_NODE_LEFT, EVT_NODE_JOINED);
this.txDeadlockDetection = new TxDeadlockDetection(cctx);
cctx.gridIO().addMessageListener(TOPIC_TX, new DeadlockDetectionListener());
cctx.txMetrics().onTxManagerStarted();
keyCollisionsInfo = new KeyCollisionsHolder();
distributedTransactionConfiguration = new DistributedTransactionConfiguration(cctx.kernalContext(), log, (String name, Long oldVal, Long newVal) -> {
if (!Objects.equals(oldVal, newVal)) {
scheduleDumpTask(IGNITE_LONG_OPERATIONS_DUMP_TIMEOUT, () -> cctx.kernalContext().closure().runLocalSafe(() -> cctx.kernalContext().cache().context().exchange().dumpLongRunningOperations(newVal)), newVal);
}
}, (String name, Integer oldVal, Integer newVal) -> {
if (!Objects.equals(oldVal, newVal)) {
scheduleDumpTask(IGNITE_DUMP_TX_COLLISIONS_INTERVAL, this::collectTxCollisionsInfo, newVal);
}
});
cctx.kernalContext().systemView().registerView(TXS_MON_LIST, TXS_MON_LIST_DESC, new TransactionViewWalker(), new ReadOnlyCollectionView2X<>(idMap.values(), nearIdMap.values()), TransactionView::new);
}
use of org.apache.ignite.spi.systemview.view.TransactionView in project ignite by apache.
the class SystemViewSelfTest method testTransactions.
/**
*/
@Test
public void testTransactions() throws Exception {
try (IgniteEx g = startGrid(0)) {
IgniteCache<Integer, Integer> cache1 = g.createCache(new CacheConfiguration<Integer, Integer>("c1").setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL));
IgniteCache<Integer, Integer> cache2 = g.createCache(new CacheConfiguration<Integer, Integer>("c2").setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL));
SystemView<TransactionView> txs = g.context().systemView().view(TXS_MON_LIST);
assertEquals(0, F.size(txs.iterator(), alwaysTrue()));
CountDownLatch latch = new CountDownLatch(1);
try {
AtomicInteger cntr = new AtomicInteger();
GridTestUtils.runMultiThreadedAsync(() -> {
try (Transaction tx = g.transactions().withLabel("test").txStart(PESSIMISTIC, REPEATABLE_READ)) {
cache1.put(cntr.incrementAndGet(), cntr.incrementAndGet());
cache1.put(cntr.incrementAndGet(), cntr.incrementAndGet());
latch.await();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}, 5, "xxx");
boolean res = waitForCondition(() -> txs.size() == 5, 10_000L);
assertTrue(res);
TransactionView txv = txs.iterator().next();
assertEquals(g.localNode().id(), txv.localNodeId());
assertEquals(txv.isolation(), REPEATABLE_READ);
assertEquals(txv.concurrency(), PESSIMISTIC);
assertEquals(txv.state(), ACTIVE);
assertNotNull(txv.xid());
assertFalse(txv.system());
assertFalse(txv.implicit());
assertFalse(txv.implicitSingle());
assertTrue(txv.near());
assertFalse(txv.dht());
assertTrue(txv.colocated());
assertTrue(txv.local());
assertEquals("test", txv.label());
assertFalse(txv.onePhaseCommit());
assertFalse(txv.internal());
assertEquals(0, txv.timeout());
assertTrue(txv.startTime() <= System.currentTimeMillis());
assertEquals(String.valueOf(cacheId(cache1.getName())), txv.cacheIds());
// Only pessimistic transactions are supported when MVCC is enabled.
if (Objects.equals(System.getProperty(IgniteSystemProperties.IGNITE_FORCE_MVCC_MODE_IN_TESTS), "true"))
return;
GridTestUtils.runMultiThreadedAsync(() -> {
try (Transaction tx = g.transactions().txStart(OPTIMISTIC, SERIALIZABLE)) {
cache1.put(cntr.incrementAndGet(), cntr.incrementAndGet());
cache1.put(cntr.incrementAndGet(), cntr.incrementAndGet());
cache2.put(cntr.incrementAndGet(), cntr.incrementAndGet());
latch.await();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}, 5, "xxx");
res = waitForCondition(() -> txs.size() == 10, 10_000L);
assertTrue(res);
for (TransactionView tx : txs) {
if (PESSIMISTIC == tx.concurrency())
continue;
assertEquals(g.localNode().id(), tx.localNodeId());
assertEquals(tx.isolation(), SERIALIZABLE);
assertEquals(tx.concurrency(), OPTIMISTIC);
assertEquals(tx.state(), ACTIVE);
assertNotNull(tx.xid());
assertFalse(tx.system());
assertFalse(tx.implicit());
assertFalse(tx.implicitSingle());
assertTrue(tx.near());
assertFalse(tx.dht());
assertTrue(tx.colocated());
assertTrue(tx.local());
assertNull(tx.label());
assertFalse(tx.onePhaseCommit());
assertFalse(tx.internal());
assertEquals(0, tx.timeout());
assertTrue(tx.startTime() <= System.currentTimeMillis());
String s1 = cacheId(cache1.getName()) + "," + cacheId(cache2.getName());
String s2 = cacheId(cache2.getName()) + "," + cacheId(cache1.getName());
assertTrue(s1.equals(tx.cacheIds()) || s2.equals(tx.cacheIds()));
}
} finally {
latch.countDown();
}
boolean res = waitForCondition(() -> txs.size() == 0, 10_000L);
assertTrue(res);
}
}
Aggregations