use of org.apache.ignite.internal.processors.cache.distributed.GridDistributedTxMapping in project ignite by apache.
the class GridNearTxFinishFuture method ackBackup.
/**
*/
private void ackBackup() {
if (mappings.empty())
return;
if (!tx.needReturnValue() || !tx.implicit())
// GridCacheReturn was not saved at backup.
return;
GridDistributedTxMapping mapping = mappings.singleMapping();
if (mapping != null) {
UUID nodeId = mapping.primary().id();
Collection<UUID> backups = tx.transactionNodes().get(nodeId);
if (!F.isEmpty(backups)) {
assert backups.size() == 1 : backups;
UUID backupId = F.first(backups);
ClusterNode backup = cctx.discovery().node(backupId);
// Nothing to do if backup has left the grid.
if (backup == null) {
// No-op.
} else if (backup.isLocal())
cctx.tm().removeTxReturn(tx.xidVersion());
else
cctx.tm().sendDeferredAckResponse(backupId, tx.xidVersion());
}
}
}
use of org.apache.ignite.internal.processors.cache.distributed.GridDistributedTxMapping in project ignite by apache.
the class GridNearTxLocal method addEntryMapping.
/**
* @param maps Mappings.
*/
void addEntryMapping(@Nullable Collection<GridDistributedTxMapping> maps) {
if (!F.isEmpty(maps)) {
for (GridDistributedTxMapping map : maps) {
ClusterNode primary = map.primary();
GridDistributedTxMapping m = mappings.get(primary.id());
if (m == null) {
mappings.put(m = new GridDistributedTxMapping(primary));
if (map.explicitLock())
m.markExplicitLock();
}
for (IgniteTxEntry entry : map.entries()) m.add(entry);
}
if (log.isDebugEnabled())
log.debug("Added mappings to transaction [locId=" + cctx.localNodeId() + ", mappings=" + maps + ", tx=" + this + ']');
}
}
use of org.apache.ignite.internal.processors.cache.distributed.GridDistributedTxMapping in project ignite by apache.
the class GridNearTxPrepareFutureAdapter method onPrepareResponse.
/**
* @param m Mapping.
* @param res Response.
* @param updateMapping Update mapping flag.
*/
@SuppressWarnings("ThrowableResultOfMethodCallIgnored")
final void onPrepareResponse(GridDistributedTxMapping m, GridNearTxPrepareResponse res, boolean updateMapping) {
if (res == null)
return;
assert res.error() == null : res;
if (tx.onePhaseCommit() && !res.onePhaseCommit())
tx.onePhaseCommit(false);
UUID nodeId = m.primary().id();
for (Map.Entry<IgniteTxKey, CacheVersionedValue> entry : res.ownedValues().entrySet()) {
IgniteTxEntry txEntry = tx.entry(entry.getKey());
assert txEntry != null;
GridCacheContext cacheCtx = txEntry.context();
while (true) {
try {
if (cacheCtx.isNear()) {
GridNearCacheEntry nearEntry = (GridNearCacheEntry) txEntry.cached();
CacheVersionedValue tup = entry.getValue();
nearEntry.resetFromPrimary(tup.value(), tx.xidVersion(), tup.version(), nodeId, tx.topologyVersion());
} else if (txEntry.cached().detached()) {
GridDhtDetachedCacheEntry detachedEntry = (GridDhtDetachedCacheEntry) txEntry.cached();
CacheVersionedValue tup = entry.getValue();
detachedEntry.resetFromPrimary(tup.value(), tx.xidVersion());
}
break;
} catch (GridCacheEntryRemovedException ignored) {
// Retry.
txEntry.cached(cacheCtx.cache().entryEx(txEntry.key(), tx.topologyVersion()));
}
}
}
tx.implicitSingleResult(res.returnValue());
for (IgniteTxKey key : res.filterFailedKeys()) {
IgniteTxEntry txEntry = tx.entry(key);
assert txEntry != null : "Missing tx entry for write key: " + key;
txEntry.op(NOOP);
assert txEntry.context() != null;
ExpiryPolicy expiry = txEntry.context().expiryForTxEntry(txEntry);
if (expiry != null)
txEntry.ttl(CU.toTtl(expiry.getExpiryForAccess()));
}
if (!m.empty()) {
// This step is very important as near and DHT versions grow separately.
cctx.versions().onReceived(nodeId, res.dhtVersion());
if (updateMapping && m.hasNearCacheEntries()) {
GridCacheVersion writeVer = res.writeVersion();
if (writeVer == null)
writeVer = res.dhtVersion();
// Register DHT version.
m.dhtVersion(res.dhtVersion(), writeVer);
GridDistributedTxMapping map = tx.mappings().get(nodeId);
if (map != null)
map.dhtVersion(res.dhtVersion(), writeVer);
tx.readyNearLocks(m, res.pending(), res.committedVersions(), res.rolledbackVersions());
}
}
}
use of org.apache.ignite.internal.processors.cache.distributed.GridDistributedTxMapping in project ignite by apache.
the class GridNearOptimisticSerializableTxPrepareFuture method map.
/**
* @param entry Transaction entry.
* @param topVer Topology version.
* @param curMapping Current mapping.
* @param txMapping Mapping.
* @param remap Remap flag.
* @param topLocked Topology locked flag.
*/
private void map(IgniteTxEntry entry, AffinityTopologyVersion topVer, Map<UUID, GridDistributedTxMapping> curMapping, GridDhtTxMapping txMapping, boolean remap, boolean topLocked) {
GridCacheContext cacheCtx = entry.context();
List<ClusterNode> nodes = cacheCtx.isLocal() ? cacheCtx.affinity().nodesByKey(entry.key(), topVer) : cacheCtx.topology().nodes(cacheCtx.affinity().partition(entry.key()), topVer);
if (F.isEmpty(nodes)) {
onDone(new ClusterTopologyServerNotFoundException("Failed to map keys to nodes " + "(partition is not mapped to any node) [key=" + entry.key() + ", partition=" + cacheCtx.affinity().partition(entry.key()) + ", topVer=" + topVer + ']'));
return;
}
txMapping.addMapping(nodes);
ClusterNode primary = F.first(nodes);
assert primary != null;
if (log.isDebugEnabled()) {
log.debug("Mapped key to primary node [key=" + entry.key() + ", part=" + cacheCtx.affinity().partition(entry.key()) + ", primary=" + U.toShortString(primary) + ", topVer=" + topVer + ']');
}
// Must re-initialize cached entry while holding topology lock.
if (cacheCtx.isNear())
entry.cached(cacheCtx.nearTx().entryExx(entry.key(), topVer));
else if (!cacheCtx.isLocal())
entry.cached(cacheCtx.colocated().entryExx(entry.key(), topVer, true));
else
entry.cached(cacheCtx.local().entryEx(entry.key(), topVer));
if (!remap && (cacheCtx.isNear() || cacheCtx.isLocal())) {
if (entry.explicitVersion() == null) {
if (keyLockFut == null) {
keyLockFut = new KeyLockFuture();
add(keyLockFut);
}
keyLockFut.addLockKey(entry.txKey());
}
}
GridDistributedTxMapping cur = curMapping.get(primary.id());
if (cur == null) {
cur = new GridDistributedTxMapping(primary);
curMapping.put(primary.id(), cur);
cur.clientFirst(!topLocked && cctx.kernalContext().clientNode());
cur.last(true);
}
if (primary.isLocal()) {
if (cacheCtx.isNear())
tx.nearLocallyMapped(true);
else if (cacheCtx.isColocated())
tx.colocatedLocallyMapped(true);
}
cur.add(entry);
if (entry.explicitVersion() != null) {
tx.markExplicit(primary.id());
cur.markExplicitLock();
}
entry.nodeId(primary.id());
if (cacheCtx.isNear()) {
while (true) {
try {
GridNearCacheEntry cached = (GridNearCacheEntry) entry.cached();
cached.dhtNodeId(tx.xidVersion(), primary.id());
break;
} catch (GridCacheEntryRemovedException ignore) {
entry.cached(cacheCtx.near().entryEx(entry.key(), topVer));
}
}
}
}
use of org.apache.ignite.internal.processors.cache.distributed.GridDistributedTxMapping in project ignite by apache.
the class GridNearOptimisticSerializableTxPrepareFuture method prepare.
/**
* @param fut Mini future.
* @param txNodes Tx nodes.
* @param locNearEntriesFut Local future for near cache entries prepare.
* @return Prepare error if any.
*/
@Nullable
private IgniteCheckedException prepare(final MiniFuture fut, Map<UUID, Collection<UUID>> txNodes, @Nullable MiniFuture locNearEntriesFut) {
GridDistributedTxMapping m = fut.mapping();
final ClusterNode primary = m.primary();
long timeout = tx.remainingTime();
if (timeout == -1) {
IgniteCheckedException err = tx.timeoutException();
fut.onResult(err);
return err;
}
// Must lock near entries separately.
if (m.hasNearCacheEntries()) {
try {
cctx.tm().prepareTx(tx, m.nearCacheEntries());
} catch (IgniteCheckedException e) {
fut.onResult(e);
return e;
}
}
if (primary.isLocal()) {
if (locNearEntriesFut != null) {
boolean nearEntries = fut == locNearEntriesFut;
GridNearTxPrepareRequest req = createRequest(txNodes, fut, timeout, nearEntries ? m.nearEntriesReads() : m.colocatedEntriesReads(), nearEntries ? m.nearEntriesWrites() : m.colocatedEntriesWrites());
prepareLocal(req, fut, nearEntries);
} else {
GridNearTxPrepareRequest req = createRequest(txNodes, fut, timeout, m.reads(), m.writes());
prepareLocal(req, fut, m.hasNearCacheEntries());
}
} else {
try {
GridNearTxPrepareRequest req = createRequest(txNodes, fut, timeout, m.reads(), m.writes());
cctx.io().send(primary, req, tx.ioPolicy());
} catch (ClusterTopologyCheckedException e) {
e.retryReadyFuture(cctx.nextAffinityReadyFuture(tx.topologyVersion()));
fut.onNodeLeft(e);
return e;
} catch (IgniteCheckedException e) {
fut.onResult(e);
return e;
}
}
return null;
}
Aggregations