use of org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry in project ignite by apache.
the class GridNearOptimisticTxPrepareFuture method requestedKeys.
/**
* @return Keys for which {@code MiniFuture} isn't completed.
*/
@SuppressWarnings("ForLoopReplaceableByForEach")
public Set<IgniteTxKey> requestedKeys() {
synchronized (this) {
int size = futuresCountNoLock();
for (int i = 0; i < size; i++) {
IgniteInternalFuture<GridNearTxPrepareResponse> fut = future(i);
if (isMini(fut) && !fut.isDone()) {
MiniFuture miniFut = (MiniFuture) fut;
Collection<IgniteTxEntry> entries = miniFut.mapping().entries();
Set<IgniteTxKey> keys = U.newHashSet(entries.size());
for (IgniteTxEntry entry : entries) keys.add(entry.txKey());
return keys;
}
}
}
return null;
}
use of org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry in project ignite by apache.
the class GridNearOptimisticTxPrepareFuture method proceedPrepare.
/**
* Continues prepare after previous mapping successfully finished.
*
* @param m Mapping.
* @param mappings Queue of mappings.
*/
private void proceedPrepare(GridDistributedTxMapping m, @Nullable final Queue<GridDistributedTxMapping> mappings) {
if (isDone())
return;
boolean set = cctx.tm().setTxTopologyHint(tx.topologyVersionSnapshot());
try {
assert !m.empty();
final ClusterNode n = m.primary();
long timeout = tx.remainingTime();
if (timeout != -1) {
GridNearTxPrepareRequest req = new GridNearTxPrepareRequest(futId, tx.topologyVersion(), tx, timeout, null, m.writes(), m.hasNearCacheEntries(), txMapping.transactionNodes(), m.last(), tx.onePhaseCommit(), tx.needReturnValue() && tx.implicit(), tx.implicitSingle(), m.explicitLock(), tx.subjectId(), tx.taskNameHash(), m.clientFirst(), tx.activeCachesDeploymentEnabled());
for (IgniteTxEntry txEntry : m.entries()) {
if (txEntry.op() == TRANSFORM)
req.addDhtVersion(txEntry.txKey(), null);
}
// Must lock near entries separately.
if (m.hasNearCacheEntries()) {
try {
cctx.tm().prepareTx(tx, m.nearCacheEntries());
} catch (IgniteCheckedException e) {
onError(e, false);
return;
}
}
final MiniFuture fut = new MiniFuture(this, m, ++miniId, mappings);
req.miniId(fut.futureId());
// Append new future.
add(fut);
if (n.isLocal()) {
assert !(m.hasColocatedCacheEntries() && m.hasNearCacheEntries()) : m;
IgniteInternalFuture<GridNearTxPrepareResponse> prepFut = m.hasNearCacheEntries() ? cctx.tm().txHandler().prepareNearTx(n.id(), req, true) : cctx.tm().txHandler().prepareColocatedTx(tx, req);
prepFut.listen(new CI1<IgniteInternalFuture<GridNearTxPrepareResponse>>() {
@Override
public void apply(IgniteInternalFuture<GridNearTxPrepareResponse> prepFut) {
try {
fut.onResult(prepFut.get());
} catch (IgniteCheckedException e) {
fut.onResult(e);
}
}
});
} else {
try {
cctx.io().send(n, req, tx.ioPolicy());
if (msgLog.isDebugEnabled()) {
msgLog.debug("Near optimistic prepare fut, sent request [txId=" + tx.nearXidVersion() + ", node=" + n.id() + ']');
}
} catch (ClusterTopologyCheckedException e) {
e.retryReadyFuture(cctx.nextAffinityReadyFuture(tx.topologyVersion()));
fut.onNodeLeft(e, false);
} catch (IgniteCheckedException e) {
if (msgLog.isDebugEnabled()) {
msgLog.debug("Near optimistic prepare fut, failed to sent request [txId=" + tx.nearXidVersion() + ", node=" + n.id() + ", err=" + e + ']');
}
fut.onResult(e);
}
}
} else
onTimeout();
} finally {
if (set)
cctx.tm().setTxTopologyHint(null);
}
}
use of org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry in project ignite by apache.
the class GridNearOptimisticTxPrepareFuture method onTimeout.
/**
*
*/
@SuppressWarnings("ForLoopReplaceableByForEach")
private void onTimeout() {
if (cctx.tm().deadlockDetectionEnabled()) {
Set<IgniteTxKey> keys = null;
if (keyLockFut != null)
keys = new HashSet<>(keyLockFut.lockKeys);
else {
synchronized (this) {
int size = futuresCountNoLock();
for (int i = 0; i < size; i++) {
IgniteInternalFuture<GridNearTxPrepareResponse> fut = future(i);
if (isMini(fut) && !fut.isDone()) {
MiniFuture miniFut = (MiniFuture) fut;
Collection<IgniteTxEntry> entries = miniFut.mapping().entries();
keys = U.newHashSet(entries.size());
for (IgniteTxEntry entry : entries) keys.add(entry.txKey());
break;
}
}
}
}
add(new GridEmbeddedFuture<>(new IgniteBiClosure<TxDeadlock, Exception, GridNearTxPrepareResponse>() {
@Override
public GridNearTxPrepareResponse apply(TxDeadlock deadlock, Exception e) {
if (e != null)
U.warn(log, "Failed to detect deadlock.", e);
else {
e = new IgniteTxTimeoutCheckedException("Failed to acquire lock within provided timeout for " + "transaction [timeout=" + tx.timeout() + ", tx=" + tx + ']', deadlock != null ? new TransactionDeadlockException(deadlock.toString(cctx)) : null);
}
onDone(null, e);
return null;
}
}, cctx.tm().detectDeadlock(tx, keys)));
} else {
ERR_UPD.compareAndSet(this, null, new IgniteTxTimeoutCheckedException("Failed to acquire lock " + "within provided timeout for transaction [timeout=" + tx.timeout() + ", tx=" + tx + ']'));
onComplete();
}
}
use of org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry in project ignite by apache.
the class GridNearOptimisticTxPrepareFuture method prepare0.
/**
* Initializes future.
*
* @param remap Remap flag.
* @param topLocked {@code True} if thread already acquired lock preventing topology change.
*/
@Override
protected void prepare0(boolean remap, boolean topLocked) {
try {
boolean txStateCheck = remap ? tx.state() == PREPARING : tx.state(PREPARING);
if (!txStateCheck) {
if (tx.setRollbackOnly()) {
if (tx.remainingTime() == -1)
onError(new IgniteTxTimeoutCheckedException("Transaction timed out and " + "was rolled back: " + this), false);
else
onError(new IgniteCheckedException("Invalid transaction state for prepare " + "[state=" + tx.state() + ", tx=" + this + ']'), false);
} else
onError(new IgniteTxRollbackCheckedException("Invalid transaction state for " + "prepare [state=" + tx.state() + ", tx=" + this + ']'), false);
return;
}
IgniteTxEntry singleWrite = tx.singleWrite();
if (singleWrite != null)
prepareSingle(singleWrite, topLocked, remap);
else
prepare(tx.writeEntries(), topLocked, remap);
markInitialized();
} catch (TransactionTimeoutException e) {
onError(e, false);
}
}
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;
}
Aggregations