use of org.apache.ignite.transactions.TransactionRollbackException in project ignite by apache.
the class GridNearTxFinishFuture method onDone.
/** {@inheritDoc} */
@Override
public boolean onDone(IgniteInternalTx tx0, Throwable err) {
if (isDone())
return false;
synchronized (this) {
if (isDone())
return false;
boolean nodeStop = false;
if (err != null) {
tx.setRollbackOnly();
nodeStop = err instanceof NodeStoppingException;
}
if (commit) {
if (tx.commitError() != null)
err = tx.commitError();
else if (err != null)
tx.commitError(err);
}
if (initialized() || err != null) {
if (tx.needCheckBackup()) {
assert tx.onePhaseCommit();
if (err != null)
err = new TransactionRollbackException("Failed to commit transaction.", err);
try {
tx.localFinish(err == null);
} catch (IgniteCheckedException e) {
if (err != null)
err.addSuppressed(e);
else
err = e;
}
}
if (tx.onePhaseCommit()) {
boolean commit = this.commit && err == null;
if (!nodeStop)
finishOnePhase(commit);
try {
tx.tmFinish(commit);
} catch (IgniteCheckedException e) {
U.error(log, "Failed to finish tx: " + tx, e);
if (err == null)
err = e;
}
}
if (super.onDone(tx0, err)) {
if (error() instanceof IgniteTxHeuristicCheckedException) {
AffinityTopologyVersion topVer = tx.topologyVersion();
for (IgniteTxEntry e : tx.writeMap().values()) {
GridCacheContext cacheCtx = e.context();
try {
if (e.op() != NOOP && !cacheCtx.affinity().keyLocalNode(e.key(), topVer)) {
GridCacheEntryEx entry = cacheCtx.cache().peekEx(e.key());
if (entry != null)
entry.invalidate(null, tx.xidVersion());
}
} catch (Throwable t) {
U.error(log, "Failed to invalidate entry.", t);
if (t instanceof Error)
throw (Error) t;
}
}
}
// Don't forget to clean up.
cctx.mvcc().removeFuture(futId);
return true;
}
}
}
return false;
}
use of org.apache.ignite.transactions.TransactionRollbackException in project ignite by apache.
the class IgniteCacheNearRestartRollbackSelfTest method updateCache.
/**
* Updates the cache or rollback the update.
*
* @param ignite Ignite instance to use.
* @param newVal the new value to put to the entries
* @param invoke whether to use invokeAll() or putAll()
* @param rollback whether to rollback the changes or commit
* @param keys Collection of keys to update.
*/
private void updateCache(Ignite ignite, int newVal, boolean invoke, boolean rollback, Set<Integer> keys) {
final IgniteCache<Integer, Integer> cache = ignite.cache(DEFAULT_CACHE_NAME);
if (rollback) {
while (true) {
try (Transaction tx = ignite.transactions().txStart(PESSIMISTIC, REPEATABLE_READ)) {
updateEntries(cache, newVal, invoke, keys);
tx.rollback();
break;
} catch (CacheException e) {
if (e.getCause() instanceof ClusterTopologyException) {
ClusterTopologyException topEx = (ClusterTopologyException) e.getCause();
topEx.retryReadyFuture().get();
} else
throw e;
} catch (ClusterTopologyException e) {
IgniteFuture<?> fut = e.retryReadyFuture();
fut.get();
} catch (TransactionRollbackException ignore) {
// Safe to retry right away.
}
}
} else
updateEntries(cache, newVal, invoke, keys);
}
use of org.apache.ignite.transactions.TransactionRollbackException in project ignite by apache.
the class GridCacheUtils method retryTopologySafe.
/**
* @param c Closure to retry.
* @throws IgniteCheckedException If failed.
* @return Closure result.
*/
public static <S> S retryTopologySafe(final Callable<S> c) throws IgniteCheckedException {
IgniteCheckedException err = null;
for (int i = 0; i < GridCacheAdapter.MAX_RETRIES; i++) {
try {
return c.call();
} catch (ClusterGroupEmptyCheckedException | ClusterTopologyServerNotFoundException e) {
throw e;
} catch (TransactionRollbackException e) {
if (i + 1 == GridCacheAdapter.MAX_RETRIES)
throw e;
U.sleep(1);
} catch (IgniteCheckedException e) {
if (i + 1 == GridCacheAdapter.MAX_RETRIES)
throw e;
if (X.hasCause(e, ClusterTopologyCheckedException.class)) {
ClusterTopologyCheckedException topErr = e.getCause(ClusterTopologyCheckedException.class);
if (topErr instanceof ClusterGroupEmptyCheckedException || topErr instanceof ClusterTopologyServerNotFoundException)
throw e;
// IGNITE-1948: remove this check when the issue is fixed
if (topErr.retryReadyFuture() != null)
topErr.retryReadyFuture().get();
else
U.sleep(1);
} else if (X.hasCause(e, IgniteTxRollbackCheckedException.class, CachePartialUpdateCheckedException.class))
U.sleep(1);
else
throw e;
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new IgniteCheckedException(e);
}
}
// Should never happen.
throw err;
}
use of org.apache.ignite.transactions.TransactionRollbackException in project ignite by apache.
the class GridCommonAbstractTest method doInTransaction.
/**
* @param ignite Ignite instance.
* @param concurrency Transaction concurrency.
* @param isolation Transaction isolation.
* @param clo Closure.
* @return Result of closure execution.
* @throws Exception If failed.
*/
protected static <T> T doInTransaction(Ignite ignite, TransactionConcurrency concurrency, TransactionIsolation isolation, Callable<T> clo) throws Exception {
while (true) {
try (Transaction tx = ignite.transactions().txStart(concurrency, isolation)) {
T res = clo.call();
tx.commit();
return res;
} catch (CacheException e) {
if (e.getCause() instanceof ClusterTopologyException) {
ClusterTopologyException topEx = (ClusterTopologyException) e.getCause();
topEx.retryReadyFuture().get();
} else
throw e;
} catch (ClusterTopologyException e) {
IgniteFuture<?> fut = e.retryReadyFuture();
fut.get();
} catch (TransactionRollbackException ignore) {
// Safe to retry right away.
}
}
}
use of org.apache.ignite.transactions.TransactionRollbackException in project ignite by apache.
the class GridCacheTxNodeFailureSelfTest method checkPrimaryNodeFailureBackupCommit.
/**
* @param conc Transaction concurrency.
* @param backup Check backup flag.
* @param commit Check commit flag.
* @throws Exception If failed.
*/
private void checkPrimaryNodeFailureBackupCommit(final TransactionConcurrency conc, boolean backup, final boolean commit) throws Exception {
try {
startGrids(gridCount());
awaitPartitionMapExchange();
for (int i = 0; i < gridCount(); i++) info("Grid " + i + ": " + ignite(i).cluster().localNode().id());
final Ignite ignite = ignite(0);
final IgniteCache<Object, Object> cache = ignite.cache(DEFAULT_CACHE_NAME).withNoRetries();
final int key = generateKey(ignite, backup);
IgniteEx backupNode = (IgniteEx) backupNode(key, DEFAULT_CACHE_NAME);
assertNotNull(backupNode);
final CountDownLatch commitLatch = new CountDownLatch(1);
if (!commit)
communication(1).bannedClasses(Collections.<Class>singletonList(GridDhtTxPrepareRequest.class));
else {
if (!backup) {
communication(2).bannedClasses(Collections.<Class>singletonList(GridDhtTxPrepareResponse.class));
communication(3).bannedClasses(Collections.<Class>singletonList(GridDhtTxPrepareResponse.class));
} else
communication(0).bannedClasses(Collections.<Class>singletonList(GridDhtTxPrepareResponse.class));
}
IgniteInternalFuture<Object> fut = GridTestUtils.runAsync(new Callable<Object>() {
@Override
public Object call() throws Exception {
if (conc != null) {
try (Transaction tx = ignite.transactions().txStart(conc, REPEATABLE_READ)) {
cache.put(key, key);
IgniteFuture<?> fut = tx.commitAsync();
commitLatch.countDown();
try {
fut.get();
if (!commit) {
error("Transaction has been committed");
fail("Transaction has been committed: " + tx);
}
} catch (TransactionRollbackException e) {
if (commit) {
error(e.getMessage(), e);
fail("Failed to commit: " + e);
} else
assertTrue(X.hasCause(e, TransactionRollbackException.class));
}
}
} else {
IgniteFuture fut = cache.putAsync(key, key);
Thread.sleep(1000);
commitLatch.countDown();
try {
fut.get();
if (!commit) {
error("Transaction has been committed");
fail("Transaction has been committed.");
}
} catch (CacheException e) {
if (commit) {
error(e.getMessage(), e);
fail("Failed to commit: " + e);
} else
assertTrue(X.hasCause(e, TransactionRollbackException.class));
}
}
return null;
}
}, "tx-thread");
commitLatch.await();
Thread.sleep(1000);
stopGrid(1);
// Check that thread successfully finished.
fut.get();
((IgniteKernal) ignite(0)).context().discovery().topologyFuture(gridCount() + 1).get();
awaitPartitionMapExchange();
// Check there are no hanging transactions.
assertEquals(0, ((IgniteEx) ignite(0)).context().cache().context().tm().idMapSize());
assertEquals(0, ((IgniteEx) ignite(2)).context().cache().context().tm().idMapSize());
assertEquals(0, ((IgniteEx) ignite(3)).context().cache().context().tm().idMapSize());
dataCheck((IgniteKernal) ignite(0), (IgniteKernal) backupNode, key, commit);
} finally {
stopAllGrids();
}
}
Aggregations