use of org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry in project ignite by apache.
the class GridNearTxRemote method addEntries.
/**
* Adds entries to started near remote tx.
*
* @param ldr Class loader.
* @param entries Entries to add.
* @throws IgniteCheckedException If failed.
*/
public void addEntries(ClassLoader ldr, Iterable<IgniteTxEntry> entries) throws IgniteCheckedException {
for (IgniteTxEntry entry : entries) {
entry.unmarshal(cctx, true, ldr);
addEntry(entry);
}
}
use of org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry in project ignite by apache.
the class GridNearTxRemote method addEntry.
/**
* @param cacheCtx Cache context.
* @param key Key to add to read set.
* @param op Operation.
* @param val Value.
* @param drVer Data center replication version.
* @param skipStore Skip store flag.
* @throws IgniteCheckedException If failed.
* @return {@code True} if entry has been enlisted.
*/
public boolean addEntry(GridCacheContext cacheCtx, IgniteTxKey key, GridCacheOperation op, CacheObject val, @Nullable GridCacheVersion drVer, boolean skipStore, boolean keepBinary) throws IgniteCheckedException {
checkInternal(key);
GridNearCacheEntry cached = cacheCtx.near().peekExx(key.key());
try {
if (cached == null) {
evicted.add(key);
return false;
} else {
cached.unswap();
CacheObject peek = cached.peek(null);
if (peek == null && cached.evictInternal(xidVer, null, false)) {
cached.context().cache().removeIfObsolete(key.key());
evicted.add(key);
return false;
} else {
IgniteTxEntry txEntry = new IgniteTxEntry(cacheCtx, this, op, val, -1L, -1L, cached, drVer, skipStore, keepBinary);
txState.addWriteEntry(key, txEntry);
return true;
}
}
} catch (GridCacheEntryRemovedException ignore) {
evicted.add(key);
if (log.isDebugEnabled())
log.debug("Got removed entry when adding reads to remote transaction (will ignore): " + cached);
return false;
}
}
use of org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry in project ignite by apache.
the class GridNearPessimisticTxPrepareFuture method preparePessimistic.
/**
*
*/
private void preparePessimistic() {
Map<UUID, GridDistributedTxMapping> mappings = new HashMap<>();
AffinityTopologyVersion topVer = tx.topologyVersion();
GridDhtTxMapping txMapping = new GridDhtTxMapping();
boolean hasNearCache = false;
for (IgniteTxEntry txEntry : tx.allEntries()) {
txEntry.clearEntryReadVersion();
GridCacheContext cacheCtx = txEntry.context();
if (cacheCtx.isNear())
hasNearCache = true;
List<ClusterNode> nodes;
if (!cacheCtx.isLocal()) {
GridDhtPartitionTopology top = cacheCtx.topology();
nodes = top.nodes(cacheCtx.affinity().partition(txEntry.key()), topVer);
} else
nodes = cacheCtx.affinity().nodesByKey(txEntry.key(), topVer);
assert !nodes.isEmpty();
ClusterNode primary = nodes.get(0);
GridDistributedTxMapping nodeMapping = mappings.get(primary.id());
if (nodeMapping == null)
mappings.put(primary.id(), nodeMapping = new GridDistributedTxMapping(primary));
txEntry.nodeId(primary.id());
nodeMapping.add(txEntry);
txMapping.addMapping(nodes);
}
tx.transactionNodes(txMapping.transactionNodes());
if (!hasNearCache)
checkOnePhase(txMapping);
long timeout = tx.remainingTime();
if (timeout == -1) {
onDone(new IgniteTxTimeoutCheckedException("Transaction timed out and was rolled back: " + tx));
return;
}
int miniId = 0;
Map<UUID, Collection<UUID>> txNodes = txMapping.transactionNodes();
for (final GridDistributedTxMapping m : mappings.values()) {
final ClusterNode primary = m.primary();
if (primary.isLocal()) {
if (m.hasNearCacheEntries() && m.hasColocatedCacheEntries()) {
GridNearTxPrepareRequest nearReq = createRequest(txMapping.transactionNodes(), m, timeout, m.nearEntriesReads(), m.nearEntriesWrites());
prepareLocal(nearReq, m, ++miniId, true);
GridNearTxPrepareRequest colocatedReq = createRequest(txNodes, m, timeout, m.colocatedEntriesReads(), m.colocatedEntriesWrites());
prepareLocal(colocatedReq, m, ++miniId, false);
} else {
GridNearTxPrepareRequest req = createRequest(txNodes, m, timeout, m.reads(), m.writes());
prepareLocal(req, m, ++miniId, m.hasNearCacheEntries());
}
} else {
GridNearTxPrepareRequest req = createRequest(txNodes, m, timeout, m.reads(), m.writes());
final MiniFuture fut = new MiniFuture(m, ++miniId);
req.miniId(fut.futureId());
add(fut);
try {
cctx.io().send(primary, req, tx.ioPolicy());
if (msgLog.isDebugEnabled()) {
msgLog.debug("Near pessimistic prepare, sent request [txId=" + tx.nearXidVersion() + ", node=" + primary.id() + ']');
}
} catch (ClusterTopologyCheckedException e) {
e.retryReadyFuture(cctx.nextAffinityReadyFuture(topVer));
fut.onNodeLeft(e);
} catch (IgniteCheckedException e) {
if (msgLog.isDebugEnabled()) {
msgLog.debug("Near pessimistic prepare, failed send request [txId=" + tx.nearXidVersion() + ", node=" + primary.id() + ", err=" + e + ']');
}
fut.onError(e);
break;
}
}
}
markInitialized();
}
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);
} 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.internal.processors.cache.transactions.IgniteTxEntry in project ignite by apache.
the class GridNearOptimisticSerializableTxPrepareFuture method prepare.
/**
* @param reads Read entries.
* @param writes Write entries.
* @param remap Remap flag.
* @param topLocked Topology locked flag.
*/
@SuppressWarnings("unchecked")
private void prepare(Iterable<IgniteTxEntry> reads, Iterable<IgniteTxEntry> writes, boolean remap, boolean topLocked) {
AffinityTopologyVersion topVer = tx.topologyVersion();
assert topVer.topologyVersion() > 0;
GridDhtTxMapping txMapping = new GridDhtTxMapping();
Map<UUID, GridDistributedTxMapping> mappings = new HashMap<>();
boolean hasNearCache = false;
for (IgniteTxEntry write : writes) {
map(write, topVer, mappings, txMapping, remap, topLocked);
if (write.context().isNear())
hasNearCache = true;
}
for (IgniteTxEntry read : reads) map(read, topVer, mappings, txMapping, remap, topLocked);
if (keyLockFut != null)
keyLockFut.onAllKeysAdded();
if (isDone()) {
if (log.isDebugEnabled())
log.debug("Abandoning (re)map because future is done: " + this);
return;
}
tx.addEntryMapping(mappings.values());
cctx.mvcc().recheckPendingLocks();
tx.transactionNodes(txMapping.transactionNodes());
if (!hasNearCache)
checkOnePhase(txMapping);
MiniFuture locNearEntriesFut = null;
// Create futures in advance to have all futures when process {@link GridNearTxPrepareResponse#clientRemapVersion}.
for (GridDistributedTxMapping m : mappings.values()) {
assert !m.empty();
MiniFuture fut = new MiniFuture(this, m, ++miniId);
add(fut);
if (m.primary().isLocal() && m.hasNearCacheEntries() && m.hasColocatedCacheEntries()) {
assert locNearEntriesFut == null;
locNearEntriesFut = fut;
add(new MiniFuture(this, m, ++miniId));
}
}
Collection<IgniteInternalFuture<?>> futs = (Collection) futures();
Iterator<IgniteInternalFuture<?>> it = futs.iterator();
while (it.hasNext()) {
IgniteInternalFuture<?> fut0 = it.next();
if (skipFuture(remap, fut0))
continue;
MiniFuture fut = (MiniFuture) fut0;
IgniteCheckedException err = prepare(fut, txMapping.transactionNodes(), locNearEntriesFut);
if (err != null) {
while (it.hasNext()) {
fut0 = it.next();
if (skipFuture(remap, fut0))
continue;
fut = (MiniFuture) fut0;
tx.removeMapping(fut.mapping().primary().id());
fut.onResult(new IgniteCheckedException("Failed to prepare transaction.", err));
}
break;
}
}
markInitialized();
}
Aggregations