use of org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry in project ignite by apache.
the class GridNearLockFuture method addEntry.
/**
* Adds entry to future.
*
* @param topVer Topology version.
* @param entry Entry to add.
* @param dhtNodeId DHT node ID.
* @return Lock candidate.
* @throws GridCacheEntryRemovedException If entry was removed.
*/
@Nullable
private GridCacheMvccCandidate addEntry(AffinityTopologyVersion topVer, GridNearCacheEntry entry, UUID dhtNodeId) throws GridCacheEntryRemovedException {
assert Thread.holdsLock(this);
// Check if lock acquisition is timed out.
if (timedOut)
return null;
// Add local lock first, as it may throw GridCacheEntryRemovedException.
GridCacheMvccCandidate c = entry.addNearLocal(dhtNodeId, threadId, lockVer, topVer, timeout, !inTx(), inTx(), implicitSingleTx(), false);
if (inTx()) {
IgniteTxEntry txEntry = tx.entry(entry.txKey());
txEntry.cached(entry);
}
entries.add(entry);
if (c == null && timeout < 0) {
if (log.isDebugEnabled())
log.debug("Failed to acquire lock with negative timeout: " + entry);
onFailed(false);
return null;
}
// Double check if lock acquisition has already timed out.
if (timedOut) {
entry.removeLock(lockVer);
return null;
}
return c;
}
use of org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry 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, true);
} 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, nodeStop, true);
} 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 && !nodeStop) {
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(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.internal.processors.cache.transactions.IgniteTxEntry in project ignite by apache.
the class GridDhtTxPrepareFuture method prepare.
/**
* Initializes future.
*
* @param reads Read entries.
* @param writes Write entries.
* @param txNodes Transaction nodes mapping.
*/
@SuppressWarnings("TypeMayBeWeakened")
public void prepare(Collection<IgniteTxEntry> reads, Collection<IgniteTxEntry> writes, Map<UUID, Collection<UUID>> txNodes) {
if (tx.empty()) {
tx.setRollbackOnly();
onDone((GridNearTxPrepareResponse) null);
}
this.reads = reads;
this.writes = writes;
this.txNodes = txNodes;
boolean ser = tx.serializable() && tx.optimistic();
if (!F.isEmpty(writes) || (ser && !F.isEmpty(reads))) {
Map<Integer, Collection<KeyCacheObject>> forceKeys = null;
for (IgniteTxEntry entry : writes) forceKeys = checkNeedRebalanceKeys(entry, forceKeys);
if (ser) {
for (IgniteTxEntry entry : reads) forceKeys = checkNeedRebalanceKeys(entry, forceKeys);
}
forceKeysFut = forceRebalanceKeys(forceKeys);
}
readyLocks();
if (timeoutObj != null) {
// Start timeout tracking after 'readyLocks' to avoid race with timeout processing.
cctx.time().addTimeoutObject(timeoutObj);
}
mapIfLocked();
}
use of org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry in project ignite by apache.
the class GridDhtTxLocal method prepareAsync.
/**
* Prepares next batch of entries in dht transaction.
*
* @param reads Read entries.
* @param writes Write entries.
* @param verMap Version map.
* @param msgId Message ID.
* @param nearMiniId Near mini future ID.
* @param txNodes Transaction nodes mapping.
* @param last {@code True} if this is last prepare request.
* @return Future that will be completed when locks are acquired.
*/
public final IgniteInternalFuture<GridNearTxPrepareResponse> prepareAsync(@Nullable Collection<IgniteTxEntry> reads, @Nullable Collection<IgniteTxEntry> writes, Map<IgniteTxKey, GridCacheVersion> verMap, long msgId, int nearMiniId, Map<UUID, Collection<UUID>> txNodes, boolean last) {
// 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, nearMiniId, verMap, last, needReturnValue()))) {
GridDhtTxPrepareFuture f = prepFut;
assert f.nearMiniId() == nearMiniId : "Wrong near mini id on existing future " + "[futMiniId=" + f.nearMiniId() + ", miniId=" + nearMiniId + ", fut=" + f + ']';
if (timeout == -1)
f.onError(timeoutException());
return chainOnePhasePrepare(f);
}
} else {
assert fut.nearMiniId() == nearMiniId : "Wrong near mini id on existing future " + "[futMiniId=" + fut.nearMiniId() + ", miniId=" + nearMiniId + ", 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 (reads != null) {
for (IgniteTxEntry e : reads) addEntry(msgId, e);
}
if (writes != null) {
for (IgniteTxEntry e : writes) addEntry(msgId, e);
}
userPrepare(null);
// Make sure to add future before calling prepare on it.
cctx.mvcc().addFuture(fut);
if (isSystemInvalidate())
fut.complete();
else
fut.prepare(reads, writes, txNodes);
} catch (IgniteTxTimeoutCheckedException | IgniteTxOptimisticCheckedException e) {
fut.onError(e);
} catch (IgniteCheckedException e) {
setRollbackOnly();
fut.onError(new IgniteTxRollbackCheckedException("Failed to prepare transaction: " + this, e));
try {
rollbackDhtLocal();
} catch (IgniteTxOptimisticCheckedException e1) {
if (log.isDebugEnabled())
log.debug("Failed optimistically to prepare transaction [tx=" + this + ", e=" + e1 + ']');
fut.onError(e);
} catch (IgniteCheckedException e1) {
U.error(log, "Failed to rollback transaction: " + this, e1);
}
}
return chainOnePhasePrepare(fut);
}
use of org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry in project ignite by apache.
the class IgniteCacheContainsKeyAbstractSelfTest method txContainsKey.
/**
* Checks if transaction has given key enlisted.
*
* @param tx Transaction to check.
* @param key Key to check.
* @return {@code True} if key was enlisted.
*/
private boolean txContainsKey(Transaction tx, String key) {
TransactionProxyImpl<String, Integer> proxy = (TransactionProxyImpl<String, Integer>) tx;
IgniteInternalTx txEx = proxy.tx();
IgniteTxEntry entry = txEx.entry(context(0).txKey(context(0).toCacheKeyObject(key)));
return entry != null;
}
Aggregations