use of org.apache.ignite.internal.transactions.IgniteTxOptimisticCheckedException in project ignite by apache.
the class IgniteTxHandler method processDhtTxPrepareRequest.
/**
* @param nodeId Sender node ID.
* @param req Request.
*/
private void processDhtTxPrepareRequest(final UUID nodeId, final GridDhtTxPrepareRequest req) {
try (TraceSurroundings ignored = MTC.support(ctx.kernalContext().tracing().create(TX_PROCESS_DHT_PREPARE_REQ, MTC.span()))) {
if (txPrepareMsgLog.isDebugEnabled()) {
txPrepareMsgLog.debug("Received dht prepare request [txId=" + req.nearXidVersion() + ", dhtTxId=" + req.version() + ", node=" + nodeId + ']');
}
assert nodeId != null;
assert req != null;
assert req.transactionNodes() != null;
GridDhtTxRemote dhtTx = null;
GridNearTxRemote nearTx = null;
GridDhtTxPrepareResponse res;
try {
res = new GridDhtTxPrepareResponse(req.partition(), req.version(), req.futureId(), req.miniId(), req.deployInfo() != null);
// Start near transaction first.
nearTx = !F.isEmpty(req.nearWrites()) ? startNearRemoteTx(ctx.deploy().globalLoader(), nodeId, req) : null;
dhtTx = startRemoteTx(nodeId, req, res);
// Set evicted keys from near transaction.
if (nearTx != null)
res.nearEvicted(nearTx.evicted());
List<IgniteTxKey> writesCacheMissed = req.nearWritesCacheMissed();
if (writesCacheMissed != null) {
Collection<IgniteTxKey> evicted0 = res.nearEvicted();
if (evicted0 != null)
writesCacheMissed.addAll(evicted0);
res.nearEvicted(writesCacheMissed);
}
if (dhtTx != null)
req.txState(dhtTx.txState());
else if (nearTx != null)
req.txState(nearTx.txState());
if (dhtTx != null && !F.isEmpty(dhtTx.invalidPartitions()))
res.invalidPartitionsByCacheId(dhtTx.invalidPartitions());
if (req.onePhaseCommit()) {
assert req.last();
if (dhtTx != null) {
dhtTx.onePhaseCommit(true);
dhtTx.needReturnValue(req.needReturnValue());
finish(dhtTx, req);
}
if (nearTx != null) {
nearTx.onePhaseCommit(true);
finish(nearTx, req);
}
}
} catch (IgniteCheckedException e) {
if (e instanceof IgniteTxRollbackCheckedException)
U.error(log, "Transaction was rolled back before prepare completed: " + req, e);
else if (e instanceof IgniteTxOptimisticCheckedException) {
if (log.isDebugEnabled())
log.debug("Optimistic failure for remote transaction (will rollback): " + req);
} else
U.error(log, "Failed to process prepare request: " + req, e);
if (nearTx != null)
try {
nearTx.rollbackRemoteTx();
} catch (Throwable e1) {
e.addSuppressed(e1);
}
res = new GridDhtTxPrepareResponse(req.partition(), req.version(), req.futureId(), req.miniId(), e, req.deployInfo() != null);
}
if (req.onePhaseCommit()) {
IgniteInternalFuture completeFut;
IgniteInternalFuture<IgniteInternalTx> dhtFin = dhtTx == null ? null : dhtTx.done() ? null : dhtTx.finishFuture();
final IgniteInternalFuture<IgniteInternalTx> nearFin = nearTx == null ? null : nearTx.done() ? null : nearTx.finishFuture();
if (dhtFin != null && nearFin != null) {
GridCompoundFuture fut = new GridCompoundFuture();
fut.add(dhtFin);
fut.add(nearFin);
fut.markInitialized();
completeFut = fut;
} else
completeFut = dhtFin != null ? dhtFin : nearFin;
if (completeFut != null) {
final GridDhtTxPrepareResponse res0 = res;
final GridDhtTxRemote dhtTx0 = dhtTx;
final GridNearTxRemote nearTx0 = nearTx;
completeFut.listen(new CI1<IgniteInternalFuture<IgniteInternalTx>>() {
@Override
public void apply(IgniteInternalFuture<IgniteInternalTx> fut) {
sendReply(nodeId, req, res0, dhtTx0, nearTx0);
}
});
} else
sendReply(nodeId, req, res, dhtTx, nearTx);
} else
sendReply(nodeId, req, res, dhtTx, nearTx);
assert req.txState() != null || res.error() != null || (dhtTx == null && nearTx == null) : req + " tx=" + dhtTx + " nearTx=" + nearTx;
}
}
use of org.apache.ignite.internal.transactions.IgniteTxOptimisticCheckedException in project ignite by apache.
the class GridDhtTxLocal method prepareAsync.
/**
* Prepares next batch of entries in dht transaction.
*
* @param req Prepare request.
* @return Future that will be completed when locks are acquired.
*/
public final IgniteInternalFuture<GridNearTxPrepareResponse> prepareAsync(GridNearTxPrepareRequest req) {
// In optimistic mode prepare still can be called explicitly from salvageTx.
GridDhtTxPrepareFuture fut = prepFut;
long timeout = remainingTime();
if (fut == null) {
init();
// Future must be created before any exception can be thrown.
if (!PREP_FUT_UPD.compareAndSet(this, null, fut = new GridDhtTxPrepareFuture(cctx, this, timeout, req.miniId(), req.dhtVersions(), req.last(), needReturnValue()))) {
GridDhtTxPrepareFuture f = prepFut;
assert f.nearMiniId() == req.miniId() : "Wrong near mini id on existing future " + "[futMiniId=" + f.nearMiniId() + ", miniId=" + req.miniId() + ", fut=" + f + ']';
if (timeout == -1)
f.onError(timeoutException());
return chainOnePhasePrepare(f);
}
} else {
assert fut.nearMiniId() == req.miniId() : "Wrong near mini id on existing future " + "[futMiniId=" + fut.nearMiniId() + ", miniId=" + req.miniId() + ", fut=" + fut + ']';
// Prepare was called explicitly.
return chainOnePhasePrepare(fut);
}
if (state() != PREPARING) {
if (!state(PREPARING)) {
if (state() == PREPARED && isSystemInvalidate())
fut.complete();
if (setRollbackOnly()) {
if (timeout == -1)
fut.onError(new IgniteTxTimeoutCheckedException("Transaction timed out and was rolled back: " + this));
else
fut.onError(new IgniteCheckedException("Invalid transaction state for prepare [state=" + state() + ", tx=" + this + ']'));
} else
fut.onError(new IgniteTxRollbackCheckedException("Invalid transaction state for prepare [state=" + state() + ", tx=" + this + ']'));
return fut;
}
}
try {
if (req.reads() != null) {
for (IgniteTxEntry e : req.reads()) addEntry(req.messageId(), e);
}
if (req.writes() != null) {
for (IgniteTxEntry e : req.writes()) addEntry(req.messageId(), e);
}
userPrepare(null);
// Make sure to add future before calling prepare on it.
cctx.mvcc().addFuture(fut);
if (isSystemInvalidate())
fut.complete();
else
fut.prepare(req);
} catch (IgniteTxTimeoutCheckedException | IgniteTxRollbackCheckedException | IgniteTxOptimisticCheckedException e) {
fut.onError(e);
} catch (IgniteCheckedException e) {
setRollbackOnly();
fut.onError(new IgniteTxRollbackCheckedException("Failed to prepare transaction: " + CU.txString(this), e));
}
return chainOnePhasePrepare(fut);
}
use of org.apache.ignite.internal.transactions.IgniteTxOptimisticCheckedException in project ignite by apache.
the class GridDhtTxPrepareFuture method versionCheckError.
/**
* @param entry Entry.
* @return Optimistic version check error.
*/
private IgniteTxOptimisticCheckedException versionCheckError(IgniteTxEntry entry) {
StringBuilder msg = new StringBuilder("Failed to prepare transaction, read/write conflict [");
GridCacheContext cctx = entry.context();
try {
Object key = cctx.unwrapBinaryIfNeeded(entry.key(), entry.keepBinary(), false, null);
assert key != null : entry.key();
if (S.includeSensitive())
msg.append("key=").append(key.toString()).append(", keyCls=").append(key.getClass().getName());
} catch (Exception e) {
msg.append("key=<failed to get key: ").append(e.toString()).append(">");
}
try {
GridCacheEntryEx entryEx = entry.cached();
CacheObject cacheVal = entryEx != null ? entryEx.rawGet() : null;
Object val = cacheVal != null ? cctx.unwrapBinaryIfNeeded(cacheVal, entry.keepBinary(), false, null) : null;
if (val != null) {
if (S.includeSensitive())
msg.append(", val=").append(val.toString()).append(", valCls=").append(val.getClass().getName());
} else
msg.append(", val=null");
} catch (Exception e) {
msg.append(", val=<failed to get value: ").append(e.toString()).append(">");
}
msg.append(", cache=").append(cctx.name()).append(", thread=").append(Thread.currentThread()).append("]");
return new IgniteTxOptimisticCheckedException(msg.toString());
}
use of org.apache.ignite.internal.transactions.IgniteTxOptimisticCheckedException in project ignite by apache.
the class GridNearTxLocal method prepareAsyncLocal.
/**
* Prepares next batch of entries in dht transaction.
*
* @param req Prepare request.
* @return Future that will be completed when locks are acquired.
*/
public IgniteInternalFuture<GridNearTxPrepareResponse> prepareAsyncLocal(GridNearTxPrepareRequest req) {
long timeout = remainingTime();
if (state() != PREPARING) {
if (timeout == -1)
return new GridFinishedFuture<>(timeoutException());
setRollbackOnly();
return new GridFinishedFuture<>(rollbackException());
}
if (timeout == -1)
return new GridFinishedFuture<>(timeoutException());
init();
GridDhtTxPrepareFuture fut = new GridDhtTxPrepareFuture(cctx, this, timeout, 0, Collections.<IgniteTxKey, GridCacheVersion>emptyMap(), req.last(), needReturnValue() && implicit());
try {
userPrepare((serializable() && optimistic()) ? F.concat(false, req.writes(), req.reads()) : req.writes());
// Make sure to add future before calling prepare on it.
cctx.mvcc().addFuture(fut);
if (isSystemInvalidate())
fut.complete();
else
fut.prepare(req);
} catch (IgniteTxTimeoutCheckedException | IgniteTxOptimisticCheckedException e) {
fut.onError(e);
} catch (IgniteCheckedException e) {
setRollbackOnly();
fut.onError(new IgniteTxRollbackCheckedException("Failed to prepare transaction: " + this, e));
}
return chainOnePhasePrepare(fut);
}
use of org.apache.ignite.internal.transactions.IgniteTxOptimisticCheckedException in project ignite by apache.
the class GridNearOptimisticSerializableTxPrepareFuture method onError.
/**
* @param m Failed mapping.
* @param e Error.
*/
private void onError(@Nullable GridDistributedTxMapping m, Throwable e) {
try (TraceSurroundings ignored = MTC.support(span)) {
if (X.hasCause(e, ClusterTopologyCheckedException.class) || X.hasCause(e, ClusterTopologyException.class)) {
if (tx.onePhaseCommit()) {
tx.markForBackupCheck();
onComplete();
return;
}
}
if (e instanceof IgniteTxOptimisticCheckedException) {
if (m != null)
tx.removeMapping(m.primary().id());
}
prepareError(e);
}
}
Aggregations