use of org.apache.ignite.internal.processors.cache.distributed.near.consistency.IgniteConsistencyViolationException in project ignite by apache.
the class GridCacheAdapter method getWithRepairAsync.
/**
* Performs repair and retries get if necessary.
* @param orig Original get future.
* @param repair Repair callback, used in case of inconcstency.
* @param retry Callback to original method to retry operation after repair.
*/
private <R> IgniteInternalFuture<R> getWithRepairAsync(IgniteInternalFuture<R> orig, Function<Collection<KeyCacheObject>, IgniteInternalFuture<Void>> repair, Supplier<IgniteInternalFuture<R>> retry) {
final GridNearTxLocal tx = checkCurrentTx();
final CacheOperationContext opCtx = ctx.operationContextPerCall();
GridFutureAdapter<R> fut = new GridFutureAdapter<>();
orig.listen((f) -> {
try {
fut.onDone(f.get());
} catch (IgniteConsistencyViolationException e1) {
repair.apply(e1.keys()).listen((repFut) -> {
if (repFut.error() != null)
fut.onDone(repFut.error());
else {
CacheOperationContext prevOpCtx = ctx.operationContextPerCall();
// Within the original tx.
IgniteInternalTx prevTx = ctx.tm().tx(tx);
// With the same operation context.
ctx.operationContextPerCall(opCtx);
try {
fut.onDone(retry.get().get());
} catch (IgniteCheckedException e2) {
fut.onDone(e2);
} finally {
ctx.tm().tx(prevTx);
ctx.operationContextPerCall(prevOpCtx);
}
}
});
} catch (IgniteCheckedException e1) {
fut.onDone(e1);
}
});
return fut;
}
use of org.apache.ignite.internal.processors.cache.distributed.near.consistency.IgniteConsistencyViolationException in project ignite by apache.
the class GridCacheAdapter method syncOp.
/**
* @param op Cache operation.
* @param <T> Return type.
* @return Operation result.
* @throws IgniteCheckedException If operation failed.
*/
@SuppressWarnings({ "ErrorNotRethrown", "AssignmentToCatchBlockParameter" })
@Nullable
private <T> T syncOp(SyncOp<T> op) throws IgniteCheckedException {
checkJta();
awaitLastFut();
GridNearTxLocal tx = checkCurrentTx();
if (tx == null || tx.implicit()) {
TransactionConfiguration tCfg = CU.transactionConfiguration(ctx, ctx.kernalContext().config());
CacheOperationContext opCtx = ctx.operationContextPerCall();
int retries = opCtx != null && opCtx.noRetries() ? 1 : MAX_RETRIES;
for (int i = 0; i < retries; i++) {
tx = ctx.tm().newTx(true, op.single(), ctx.systemTx() ? ctx : null, ctx.mvccEnabled() ? PESSIMISTIC : OPTIMISTIC, ctx.mvccEnabled() ? REPEATABLE_READ : READ_COMMITTED, tCfg.getDefaultTxTimeout(), !ctx.skipStore(), ctx.mvccEnabled(), 0, null, false);
assert tx != null;
try {
T t = op.op(tx);
assert tx.done() : "Transaction is not done: " + tx;
return t;
} catch (IgniteInterruptedCheckedException | IgniteTxHeuristicCheckedException | NodeStoppingException | IgniteConsistencyViolationException e) {
throw e;
} catch (IgniteCheckedException e) {
if (!(e instanceof IgniteTxRollbackCheckedException)) {
try {
tx.rollback();
if (!(e instanceof TransactionCheckedException))
e = new IgniteTxRollbackCheckedException("Transaction has been rolled back: " + tx.xid(), e);
} catch (IgniteCheckedException | AssertionError | RuntimeException e1) {
U.error(log, "Failed to rollback transaction (cache may contain stale locks): " + CU.txString(tx), e1);
if (e != e1)
e.addSuppressed(e1);
}
}
if (X.hasCause(e, ClusterTopologyCheckedException.class) && i != retries - 1) {
ClusterTopologyCheckedException topErr = e.getCause(ClusterTopologyCheckedException.class);
if (!(topErr instanceof ClusterTopologyServerNotFoundException)) {
AffinityTopologyVersion topVer = tx.topologyVersion();
assert topVer != null && topVer.topologyVersion() > 0 : tx;
AffinityTopologyVersion awaitVer = new AffinityTopologyVersion(topVer.topologyVersion() + 1, 0);
ctx.shared().exchange().affinityReadyFuture(awaitVer).get();
continue;
}
}
throw e;
} catch (RuntimeException e) {
try {
tx.rollback();
} catch (IgniteCheckedException | AssertionError | RuntimeException e1) {
U.error(log, "Failed to rollback transaction " + CU.txString(tx), e1);
}
throw e;
} finally {
ctx.tm().resetContext();
if (ctx.isNear())
ctx.near().dht().context().tm().resetContext();
}
}
// Should not happen.
throw new IgniteCheckedException("Failed to perform cache operation (maximum number of retries exceeded).");
} else
return op.op(tx);
}
use of org.apache.ignite.internal.processors.cache.distributed.near.consistency.IgniteConsistencyViolationException in project ignite by apache.
the class GridNearTxLocal method loadMissing.
/**
* @param cacheCtx Cache context.
* @param readThrough Read through flag.
* @param async if {@code True}, then loading will happen in a separate thread.
* @param keys Keys.
* @param skipVals Skip values flag.
* @param needVer If {@code true} version is required for loaded values.
* @param c Closure to be applied for loaded values.
* @param readRepairStrategy Read Repair strategy.
* @param expiryPlc Expiry policy.
* @return Future with {@code True} value if loading took place.
*/
private IgniteInternalFuture<Void> loadMissing(final GridCacheContext cacheCtx, AffinityTopologyVersion topVer, boolean readThrough, boolean async, final Collection<KeyCacheObject> keys, final boolean skipVals, final boolean needVer, boolean keepBinary, boolean recovery, ReadRepairStrategy readRepairStrategy, final ExpiryPolicy expiryPlc, final GridInClosure3<KeyCacheObject, Object, GridCacheVersion> c) {
IgniteCacheExpiryPolicy expiryPlc0 = optimistic() ? accessPolicy(cacheCtx, keys) : cacheCtx.cache().expiryPolicy(expiryPlc);
if (cacheCtx.isNear()) {
return cacheCtx.nearTx().txLoadAsync(this, topVer, keys, readThrough, needVer || !cacheCtx.config().isReadFromBackup() || (optimistic() && serializable() && readThrough), /*deserializeBinary*/
false, recovery, expiryPlc0, skipVals, needVer).chain(new C1<IgniteInternalFuture<Map<Object, Object>>, Void>() {
@Override
public Void apply(IgniteInternalFuture<Map<Object, Object>> f) {
try {
Map<Object, Object> map = f.get();
processLoaded(map, keys, needVer, c);
return null;
} catch (Exception e) {
setRollbackOnly();
throw new GridClosureException(e);
}
}
});
} else if (cacheCtx.isColocated()) {
if (readRepairStrategy != null) {
return new GridNearReadRepairCheckOnlyFuture(cacheCtx, keys, readRepairStrategy, readThrough, taskName, false, recovery, expiryPlc0, skipVals, needVer, true, this).multi().chain((fut) -> {
try {
Map<Object, Object> map = fut.get();
processLoaded(map, keys, needVer, c);
return null;
} catch (IgniteConsistencyViolationException e) {
for (KeyCacheObject key : keys) // Will be recreated after repair.
txState().removeEntry(cacheCtx.txKey(key));
throw new GridClosureException(e);
} catch (Exception e) {
setRollbackOnly();
throw new GridClosureException(e);
}
});
}
if (keys.size() == 1) {
final KeyCacheObject key = F.first(keys);
return cacheCtx.colocated().loadAsync(key, readThrough, needVer || !cacheCtx.config().isReadFromBackup() || (optimistic() && serializable() && readThrough), topVer, resolveTaskName(), /*deserializeBinary*/
false, expiryPlc0, skipVals, needVer, /*keepCacheObject*/
true, recovery, null, label()).chain(new C1<IgniteInternalFuture<Object>, Void>() {
@Override
public Void apply(IgniteInternalFuture<Object> f) {
try {
Object val = f.get();
processLoaded(key, val, needVer, skipVals, c);
return null;
} catch (Exception e) {
setRollbackOnly();
throw new GridClosureException(e);
}
}
});
} else {
return cacheCtx.colocated().loadAsync(keys, readThrough, needVer || !cacheCtx.config().isReadFromBackup() || (optimistic() && serializable() && readThrough), topVer, resolveTaskName(), /*deserializeBinary*/
false, recovery, expiryPlc0, skipVals, needVer, /*keepCacheObject*/
true, label(), null).chain(new C1<IgniteInternalFuture<Map<Object, Object>>, Void>() {
@Override
public Void apply(IgniteInternalFuture<Map<Object, Object>> f) {
try {
Map<Object, Object> map = f.get();
processLoaded(map, keys, needVer, c);
return null;
} catch (Exception e) {
setRollbackOnly();
throw new GridClosureException(e);
}
}
});
}
} else {
assert cacheCtx.isLocal();
return localCacheLoadMissing(cacheCtx, topVer, readThrough, async, keys, skipVals, needVer, keepBinary, recovery, expiryPlc, c);
}
}
use of org.apache.ignite.internal.processors.cache.distributed.near.consistency.IgniteConsistencyViolationException in project ignite by apache.
the class GridCacheAdapter method asyncOp.
/**
* @param tx Transaction.
* @param op Cache operation.
* @param opCtx Cache operation context.
* @param <T> Return type.
* @return Future.
*/
@SuppressWarnings("unchecked")
protected <T> IgniteInternalFuture<T> asyncOp(GridNearTxLocal tx, final AsyncOp<T> op, final CacheOperationContext opCtx, final boolean retry) {
IgniteInternalFuture<T> fail = asyncOpAcquire(retry);
if (fail != null)
return fail;
FutureHolder holder = lastFut.get();
holder.lock();
try {
IgniteInternalFuture fut = holder.future();
final GridNearTxLocal tx0 = tx;
final CX1 clo = new CX1<IgniteInternalFuture<T>, T>() {
@Override
public T applyx(IgniteInternalFuture<T> tFut) throws IgniteCheckedException {
try {
return tFut.get();
} catch (IgniteTxTimeoutCheckedException | IgniteTxRollbackCheckedException | NodeStoppingException | IgniteConsistencyViolationException e) {
throw e;
} catch (IgniteCheckedException e1) {
try {
tx0.rollbackNearTxLocalAsync();
} catch (Throwable e2) {
if (e1 != e2)
e1.addSuppressed(e2);
}
throw e1;
} finally {
ctx.shared().txContextReset();
}
}
};
if (fut != null && !fut.isDone()) {
IgniteInternalFuture<T> f = new GridEmbeddedFuture(fut, (IgniteOutClosure<IgniteInternalFuture>) () -> {
GridFutureAdapter resFut = new GridFutureAdapter();
ctx.kernalContext().closure().runLocalSafe((GridPlainRunnable) () -> {
IgniteInternalFuture fut0;
if (ctx.kernalContext().isStopping())
fut0 = new GridFinishedFuture<>(new IgniteCheckedException("Operation has been cancelled (node or cache is stopping)."));
else if (ctx.gate().isStopped())
fut0 = new GridFinishedFuture<>(new CacheStoppedException(ctx.name()));
else {
ctx.operationContextPerCall(opCtx);
ctx.shared().txContextReset();
try {
fut0 = op.op(tx0).chain(clo);
} finally {
// It is necessary to clear tx context in this thread as well.
ctx.shared().txContextReset();
ctx.operationContextPerCall(null);
}
}
fut0.listen((IgniteInClosure<IgniteInternalFuture>) fut01 -> {
try {
resFut.onDone(fut01.get());
} catch (Throwable ex) {
resFut.onDone(ex);
}
});
}, true);
return resFut;
});
saveFuture(holder, f, retry);
return f;
}
/**
* Wait for concurrent tx operation to finish.
* See {@link GridDhtTxLocalAdapter#updateLockFuture(IgniteInternalFuture, IgniteInternalFuture)}
*/
if (!tx0.txState().implicitSingle())
tx0.txState().awaitLastFuture(ctx.shared());
IgniteInternalFuture<T> f;
try {
f = op.op(tx).chain(clo);
} finally {
// It is necessary to clear tx context in this thread as well.
ctx.shared().txContextReset();
}
saveFuture(holder, f, retry);
if (tx.implicit())
ctx.tm().resetContext();
return f;
} finally {
holder.unlock();
}
}
Aggregations