Search in sources :

Example 36 with IgniteTxEntry

use of org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry in project ignite by apache.

the class GridCacheMessage method marshalTx.

/**
 * @param txEntries Entries to marshal.
 * @param ctx Context.
 * @throws IgniteCheckedException If failed.
 */
protected final void marshalTx(Iterable<IgniteTxEntry> txEntries, GridCacheSharedContext ctx) throws IgniteCheckedException {
    assert ctx != null;
    if (txEntries != null) {
        boolean transferExpiry = transferExpiryPolicy();
        boolean p2pEnabled = ctx.deploymentEnabled();
        for (IgniteTxEntry e : txEntries) {
            e.marshal(ctx, transferExpiry);
            GridCacheContext cctx = e.context();
            if (addDepInfo) {
                if (e.key() != null)
                    prepareObject(e.key().value(cctx.cacheObjectContext(), false), ctx);
                if (e.value() != null)
                    prepareObject(e.value().value(cctx.cacheObjectContext(), false), ctx);
                if (e.entryProcessors() != null) {
                    for (T2<EntryProcessor<Object, Object, Object>, Object[]> entProc : e.entryProcessors()) prepareObject(entProc.get1(), ctx);
                }
            } else if (p2pEnabled && e.entryProcessors() != null) {
                if (!forceAddDepInfo)
                    forceAddDepInfo = true;
                for (T2<EntryProcessor<Object, Object, Object>, Object[]> entProc : e.entryProcessors()) prepareObject(entProc.get1(), ctx);
            }
        }
    }
}
Also used : IgniteTxEntry(org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry) EntryProcessor(javax.cache.processor.EntryProcessor) T2(org.apache.ignite.internal.util.typedef.T2)

Example 37 with IgniteTxEntry

use of org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry in project ignite by apache.

the class GridDistributedTxRemoteAdapter method doneRemote.

/**
 * @param baseVer Base version.
 * @param committedVers Committed versions.
 * @param rolledbackVers Rolled back versions.
 */
@Override
public void doneRemote(GridCacheVersion baseVer, Collection<GridCacheVersion> committedVers, Collection<GridCacheVersion> rolledbackVers, Collection<GridCacheVersion> pendingVers) {
    Map<IgniteTxKey, IgniteTxEntry> readMap = txState.readMap();
    if (readMap != null && !readMap.isEmpty()) {
        for (IgniteTxEntry txEntry : readMap.values()) doneRemote(txEntry, baseVer, committedVers, rolledbackVers, pendingVers);
    }
    Map<IgniteTxKey, IgniteTxEntry> writeMap = txState.writeMap();
    if (writeMap != null && !writeMap.isEmpty()) {
        for (IgniteTxEntry txEntry : writeMap.values()) doneRemote(txEntry, baseVer, committedVers, rolledbackVers, pendingVers);
    }
}
Also used : IgniteTxEntry(org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry) IgniteTxKey(org.apache.ignite.internal.processors.cache.transactions.IgniteTxKey)

Example 38 with IgniteTxEntry

use of org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry in project ignite by apache.

the class GridDistributedTxRemoteAdapter method commitIfLocked.

/**
 * @throws IgniteCheckedException If commit failed.
 */
@SuppressWarnings({ "CatchGenericClass" })
private void commitIfLocked() throws IgniteCheckedException {
    if (state() == COMMITTING) {
        for (IgniteTxEntry txEntry : writeEntries()) {
            assert txEntry != null : "Missing transaction entry for tx: " + this;
            while (true) {
                GridCacheEntryEx entry = txEntry.cached();
                assert entry != null : "Missing cached entry for transaction entry: " + txEntry;
                try {
                    GridCacheVersion ver = txEntry.explicitVersion() != null ? txEntry.explicitVersion() : xidVer;
                    // If locks haven't been acquired yet, keep waiting.
                    if (!entry.lockedBy(ver)) {
                        if (log.isDebugEnabled())
                            log.debug("Transaction does not own lock for entry (will wait) [entry=" + entry + ", tx=" + this + ']');
                        return;
                    }
                    // While.
                    break;
                } catch (GridCacheEntryRemovedException ignore) {
                    if (log.isDebugEnabled())
                        log.debug("Got removed entry while committing (will retry): " + txEntry);
                    txEntry.cached(txEntry.context().cache().entryEx(txEntry.key(), topologyVersion()));
                }
            }
        }
        // Only one thread gets to commit.
        if (COMMIT_ALLOWED_UPD.compareAndSet(this, 0, 1)) {
            IgniteCheckedException err = null;
            Map<IgniteTxKey, IgniteTxEntry> writeMap = txState.writeMap();
            GridCacheReturnCompletableWrapper wrapper = null;
            if (!F.isEmpty(writeMap)) {
                GridCacheReturn ret = null;
                if (!near() && !local() && onePhaseCommit()) {
                    if (needReturnValue()) {
                        ret = new GridCacheReturn(null, cctx.localNodeId().equals(otherNodeId()), true, null, true);
                        // Originating node.
                        UUID origNodeId = otherNodeId();
                        cctx.tm().addCommittedTxReturn(this, wrapper = new GridCacheReturnCompletableWrapper(!cctx.localNodeId().equals(origNodeId) ? origNodeId : null));
                    } else
                        cctx.tm().addCommittedTx(this, this.nearXidVersion(), null);
                }
                // Register this transaction as completed prior to write-phase to
                // ensure proper lock ordering for removed entries.
                cctx.tm().addCommittedTx(this);
                AffinityTopologyVersion topVer = topologyVersion();
                WALPointer ptr = null;
                cctx.database().checkpointReadLock();
                try {
                    Collection<IgniteTxEntry> entries = near() || cctx.snapshot().needTxReadLogging() ? allEntries() : writeEntries();
                    List<DataEntry> dataEntries = null;
                    batchStoreCommit(writeMap().values());
                    try {
                        // Node that for near transactions we grab all entries.
                        for (IgniteTxEntry txEntry : entries) {
                            GridCacheContext cacheCtx = txEntry.context();
                            boolean replicate = cacheCtx.isDrEnabled();
                            try {
                                while (true) {
                                    try {
                                        GridCacheEntryEx cached = txEntry.cached();
                                        if (cached == null)
                                            txEntry.cached(cached = cacheCtx.cache().entryEx(txEntry.key(), topologyVersion()));
                                        if (near() && cacheCtx.dr().receiveEnabled()) {
                                            cached.markObsolete(xidVer);
                                            break;
                                        }
                                        GridNearCacheEntry nearCached = null;
                                        if (updateNearCache(cacheCtx, txEntry.key(), topVer))
                                            nearCached = cacheCtx.dht().near().peekExx(txEntry.key());
                                        if (!F.isEmpty(txEntry.entryProcessors()))
                                            txEntry.cached().unswap(false);
                                        IgniteBiTuple<GridCacheOperation, CacheObject> res = applyTransformClosures(txEntry, false, ret);
                                        GridCacheOperation op = res.get1();
                                        CacheObject val = res.get2();
                                        GridCacheVersion explicitVer = txEntry.conflictVersion();
                                        if (explicitVer == null)
                                            explicitVer = writeVersion();
                                        if (txEntry.ttl() == CU.TTL_ZERO)
                                            op = DELETE;
                                        boolean conflictNeedResolve = cacheCtx.conflictNeedResolve();
                                        GridCacheVersionConflictContext conflictCtx = null;
                                        if (conflictNeedResolve) {
                                            IgniteBiTuple<GridCacheOperation, GridCacheVersionConflictContext> drRes = conflictResolve(op, txEntry, val, explicitVer, cached);
                                            assert drRes != null;
                                            conflictCtx = drRes.get2();
                                            if (conflictCtx.isUseOld())
                                                op = NOOP;
                                            else if (conflictCtx.isUseNew()) {
                                                txEntry.ttl(conflictCtx.ttl());
                                                txEntry.conflictExpireTime(conflictCtx.expireTime());
                                            } else if (conflictCtx.isMerge()) {
                                                op = drRes.get1();
                                                val = txEntry.context().toCacheObject(conflictCtx.mergeValue());
                                                explicitVer = writeVersion();
                                                txEntry.ttl(conflictCtx.ttl());
                                                txEntry.conflictExpireTime(conflictCtx.expireTime());
                                            }
                                        } else
                                            // Nullify explicit version so that innerSet/innerRemove will work as usual.
                                            explicitVer = null;
                                        GridCacheVersion dhtVer = cached.isNear() ? writeVersion() : null;
                                        if (!near() && cacheCtx.group().persistenceEnabled() && cacheCtx.group().walEnabled() && op != NOOP && op != RELOAD && (op != READ || cctx.snapshot().needTxReadLogging())) {
                                            if (dataEntries == null)
                                                dataEntries = new ArrayList<>(entries.size());
                                            dataEntries.add(new DataEntry(cacheCtx.cacheId(), txEntry.key(), val, op, nearXidVersion(), writeVersion(), 0, txEntry.key().partition(), txEntry.updateCounter()));
                                        }
                                        if (op == CREATE || op == UPDATE) {
                                            // Invalidate only for near nodes (backups cannot be invalidated).
                                            if (isSystemInvalidate() || (isInvalidate() && cacheCtx.isNear()))
                                                cached.innerRemove(this, eventNodeId(), nodeId, false, true, true, txEntry.keepBinary(), txEntry.hasOldValue(), txEntry.oldValue(), topVer, null, replicate ? DR_BACKUP : DR_NONE, near() ? null : explicitVer, CU.subjectId(this, cctx), resolveTaskName(), dhtVer, txEntry.updateCounter());
                                            else {
                                                assert val != null : txEntry;
                                                GridCacheUpdateTxResult updRes = cached.innerSet(this, eventNodeId(), nodeId, val, false, false, txEntry.ttl(), true, true, txEntry.keepBinary(), txEntry.hasOldValue(), txEntry.oldValue(), topVer, null, replicate ? DR_BACKUP : DR_NONE, txEntry.conflictExpireTime(), near() ? null : explicitVer, CU.subjectId(this, cctx), resolveTaskName(), dhtVer, txEntry.updateCounter());
                                                if (updRes.loggedPointer() != null)
                                                    ptr = updRes.loggedPointer();
                                                // Keep near entry up to date.
                                                if (nearCached != null) {
                                                    CacheObject val0 = cached.valueBytes();
                                                    nearCached.updateOrEvict(xidVer, val0, cached.expireTime(), cached.ttl(), nodeId, topVer);
                                                }
                                            }
                                        } else if (op == DELETE) {
                                            GridCacheUpdateTxResult updRes = cached.innerRemove(this, eventNodeId(), nodeId, false, true, true, txEntry.keepBinary(), txEntry.hasOldValue(), txEntry.oldValue(), topVer, null, replicate ? DR_BACKUP : DR_NONE, near() ? null : explicitVer, CU.subjectId(this, cctx), resolveTaskName(), dhtVer, txEntry.updateCounter());
                                            if (updRes.loggedPointer() != null)
                                                ptr = updRes.loggedPointer();
                                            // Keep near entry up to date.
                                            if (nearCached != null)
                                                nearCached.updateOrEvict(xidVer, null, 0, 0, nodeId, topVer);
                                        } else if (op == RELOAD) {
                                            CacheObject reloaded = cached.innerReload();
                                            if (nearCached != null) {
                                                nearCached.innerReload();
                                                nearCached.updateOrEvict(cached.version(), reloaded, cached.expireTime(), cached.ttl(), nodeId, topVer);
                                            }
                                        } else if (op == READ) {
                                            assert near();
                                            if (log.isDebugEnabled())
                                                log.debug("Ignoring READ entry when committing: " + txEntry);
                                        } else // No-op.
                                        {
                                            if (conflictCtx == null || !conflictCtx.isUseOld()) {
                                                if (txEntry.ttl() != CU.TTL_NOT_CHANGED)
                                                    cached.updateTtl(null, txEntry.ttl());
                                                if (nearCached != null) {
                                                    CacheObject val0 = cached.valueBytes();
                                                    nearCached.updateOrEvict(xidVer, val0, cached.expireTime(), cached.ttl(), nodeId, topVer);
                                                }
                                            }
                                        }
                                        // that if we replaced removed entries.
                                        assert txEntry.op() == READ || onePhaseCommit() || // and we simply allow the commit to proceed.
                                        !cached.hasLockCandidateUnsafe(xidVer) || cached.lockedByUnsafe(xidVer) : "Transaction does not own lock for commit [entry=" + cached + ", tx=" + this + ']';
                                        // Break out of while loop.
                                        break;
                                    } catch (GridCacheEntryRemovedException ignored) {
                                        if (log.isDebugEnabled())
                                            log.debug("Attempting to commit a removed entry (will retry): " + txEntry);
                                        // Renew cached entry.
                                        txEntry.cached(cacheCtx.cache().entryEx(txEntry.key(), topologyVersion()));
                                    }
                                }
                            } catch (Throwable ex) {
                                boolean nodeStopping = X.hasCause(ex, NodeStoppingException.class);
                                // In case of error, we still make the best effort to commit,
                                // as there is no way to rollback at this point.
                                err = new IgniteTxHeuristicCheckedException("Commit produced a runtime exception " + "(all transaction entries will be invalidated): " + CU.txString(this), ex);
                                if (nodeStopping) {
                                    U.warn(log, "Failed to commit transaction, node is stopping [tx=" + this + ", err=" + ex + ']');
                                } else
                                    U.error(log, "Commit failed.", err);
                                uncommit(nodeStopping);
                                state(UNKNOWN);
                                if (ex instanceof Error)
                                    throw (Error) ex;
                            }
                        }
                        if (!near() && !F.isEmpty(dataEntries) && cctx.wal() != null)
                            cctx.wal().log(new DataRecord(dataEntries));
                        if (ptr != null && !cctx.tm().logTxRecords())
                            cctx.wal().fsync(ptr);
                    } catch (StorageException e) {
                        throw new IgniteCheckedException("Failed to log transaction record " + "(transaction will be rolled back): " + this, e);
                    }
                } finally {
                    cctx.database().checkpointReadUnlock();
                    if (wrapper != null)
                        wrapper.initialize(ret);
                }
            }
            if (err != null) {
                state(UNKNOWN);
                throw err;
            }
            cctx.tm().commitTx(this);
            state(COMMITTED);
        }
    }
}
Also used : NodeStoppingException(org.apache.ignite.internal.NodeStoppingException) ArrayList(java.util.ArrayList) IgniteTxHeuristicCheckedException(org.apache.ignite.internal.transactions.IgniteTxHeuristicCheckedException) DataEntry(org.apache.ignite.internal.pagemem.wal.record.DataEntry) GridCacheVersion(org.apache.ignite.internal.processors.cache.version.GridCacheVersion) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) GridCacheEntryRemovedException(org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException) CacheObject(org.apache.ignite.internal.processors.cache.CacheObject) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) DataRecord(org.apache.ignite.internal.pagemem.wal.record.DataRecord) UUID(java.util.UUID) WALPointer(org.apache.ignite.internal.pagemem.wal.WALPointer) IgniteTxEntry(org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry) GridCacheContext(org.apache.ignite.internal.processors.cache.GridCacheContext) GridCacheReturn(org.apache.ignite.internal.processors.cache.GridCacheReturn) AffinityTopologyVersion(org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion) GridCacheVersionConflictContext(org.apache.ignite.internal.processors.cache.version.GridCacheVersionConflictContext) GridCacheEntryEx(org.apache.ignite.internal.processors.cache.GridCacheEntryEx) GridNearCacheEntry(org.apache.ignite.internal.processors.cache.distributed.near.GridNearCacheEntry) GridCacheUpdateTxResult(org.apache.ignite.internal.processors.cache.GridCacheUpdateTxResult) IgniteTxKey(org.apache.ignite.internal.processors.cache.transactions.IgniteTxKey) GridCacheOperation(org.apache.ignite.internal.processors.cache.GridCacheOperation) GridCacheReturnCompletableWrapper(org.apache.ignite.internal.processors.cache.GridCacheReturnCompletableWrapper) StorageException(org.apache.ignite.internal.pagemem.wal.StorageException)

Example 39 with IgniteTxEntry

use of org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry in project ignite by apache.

the class GridDhtTxPrepareFuture method sendPrepareRequests.

/**
 */
private void sendPrepareRequests() {
    if (tx.onePhaseCommit() && !tx.nearMap().isEmpty()) {
        for (GridDistributedTxMapping nearMapping : tx.nearMap().values()) {
            if (!tx.dhtMap().containsKey(nearMapping.primary().id())) {
                tx.onePhaseCommit(false);
                break;
            }
        }
    }
    int miniId = 0;
    assert tx.transactionNodes() != null;
    final long timeout = timeoutObj != null ? timeoutObj.timeout : 0;
    // Create mini futures.
    for (GridDistributedTxMapping dhtMapping : tx.dhtMap().values()) {
        assert !dhtMapping.empty();
        ClusterNode n = dhtMapping.primary();
        assert !n.isLocal();
        GridDistributedTxMapping nearMapping = tx.nearMap().get(n.id());
        Collection<IgniteTxEntry> nearWrites = nearMapping == null ? null : nearMapping.writes();
        Collection<IgniteTxEntry> dhtWrites = dhtMapping.writes();
        if (F.isEmpty(dhtWrites) && F.isEmpty(nearWrites))
            continue;
        if (tx.remainingTime() == -1)
            return;
        MiniFuture fut = new MiniFuture(n.id(), ++miniId, dhtMapping, nearMapping);
        // Append new future.
        add(fut);
        assert req.transactionNodes() != null;
        GridDhtTxPrepareRequest req = new GridDhtTxPrepareRequest(futId, fut.futureId(), tx.topologyVersion(), tx, timeout, dhtWrites, nearWrites, this.req.transactionNodes(), tx.nearXidVersion(), true, tx.onePhaseCommit(), tx.subjectId(), tx.taskNameHash(), tx.activeCachesDeploymentEnabled(), tx.storeWriteThrough(), retVal);
        int idx = 0;
        for (IgniteTxEntry entry : dhtWrites) {
            try {
                GridDhtCacheEntry cached = (GridDhtCacheEntry) entry.cached();
                GridCacheContext<?, ?> cacheCtx = cached.context();
                // Do not invalidate near entry on originating transaction node.
                req.invalidateNearEntry(idx, !tx.nearNodeId().equals(n.id()) && cached.readerId(n.id()) != null);
                if (cached.isNewLocked()) {
                    List<ClusterNode> owners = cacheCtx.topology().owners(cached.partition(), tx != null ? tx.topologyVersion() : cacheCtx.affinity().affinityTopologyVersion());
                    // Do not preload if local node is a partition owner.
                    if (!owners.contains(cctx.localNode()))
                        req.markKeyForPreload(idx);
                }
                break;
            } catch (GridCacheEntryRemovedException ignore) {
                assert false : "Got removed exception on entry with dht local candidate: " + entry;
            }
            idx++;
        }
        if (!F.isEmpty(nearWrites)) {
            for (IgniteTxEntry entry : nearWrites) {
                try {
                    if (entry.explicitVersion() == null) {
                        GridCacheMvccCandidate added = entry.cached().candidate(version());
                        assert added != null : "Missing candidate for cache entry:" + entry;
                        assert added.dhtLocal();
                        if (added.ownerVersion() != null)
                            req.owned(entry.txKey(), added.ownerVersion());
                    }
                    break;
                } catch (GridCacheEntryRemovedException ignore) {
                    assert false : "Got removed exception on entry with dht local candidate: " + entry;
                }
            }
        }
        assert req.transactionNodes() != null;
        try {
            cctx.io().send(n, req, tx.ioPolicy());
            if (msgLog.isDebugEnabled()) {
                msgLog.debug("DHT prepare fut, sent request dht [txId=" + tx.nearXidVersion() + ", dhtTxId=" + tx.xidVersion() + ", node=" + n.id() + ']');
            }
        } catch (ClusterTopologyCheckedException ignored) {
            fut.onNodeLeft();
        } catch (IgniteCheckedException e) {
            if (!cctx.kernalContext().isStopping()) {
                if (msgLog.isDebugEnabled()) {
                    msgLog.debug("DHT prepare fut, failed to send request dht [txId=" + tx.nearXidVersion() + ", dhtTxId=" + tx.xidVersion() + ", node=" + n.id() + ']');
                }
                fut.onResult(e);
            } else {
                if (msgLog.isDebugEnabled()) {
                    msgLog.debug("DHT prepare fut, failed to send request dht, ignore [txId=" + tx.nearXidVersion() + ", dhtTxId=" + tx.xidVersion() + ", node=" + n.id() + ", err=" + e + ']');
                }
            }
        }
    }
    for (GridDistributedTxMapping nearMapping : tx.nearMap().values()) {
        if (!tx.dhtMap().containsKey(nearMapping.primary().id())) {
            if (tx.remainingTime() == -1)
                return;
            MiniFuture fut = new MiniFuture(nearMapping.primary().id(), ++miniId, null, nearMapping);
            // Append new future.
            add(fut);
            GridDhtTxPrepareRequest req = new GridDhtTxPrepareRequest(futId, fut.futureId(), tx.topologyVersion(), tx, timeout, null, nearMapping.writes(), tx.transactionNodes(), tx.nearXidVersion(), true, tx.onePhaseCommit(), tx.subjectId(), tx.taskNameHash(), tx.activeCachesDeploymentEnabled(), tx.storeWriteThrough(), retVal);
            for (IgniteTxEntry entry : nearMapping.entries()) {
                if (CU.writes().apply(entry)) {
                    try {
                        if (entry.explicitVersion() == null) {
                            GridCacheMvccCandidate added = entry.cached().candidate(version());
                            assert added != null : "Null candidate for non-group-lock entry " + "[added=" + added + ", entry=" + entry + ']';
                            assert added.dhtLocal() : "Got non-dht-local candidate for prepare future" + "[added=" + added + ", entry=" + entry + ']';
                            if (added != null && added.ownerVersion() != null)
                                req.owned(entry.txKey(), added.ownerVersion());
                        }
                        break;
                    } catch (GridCacheEntryRemovedException ignore) {
                        assert false : "Got removed exception on entry with dht local candidate: " + entry;
                    }
                }
            }
            assert req.transactionNodes() != null;
            try {
                cctx.io().send(nearMapping.primary(), req, tx.ioPolicy());
                if (msgLog.isDebugEnabled()) {
                    msgLog.debug("DHT prepare fut, sent request near [txId=" + tx.nearXidVersion() + ", dhtTxId=" + tx.xidVersion() + ", node=" + nearMapping.primary().id() + ']');
                }
            } catch (ClusterTopologyCheckedException ignored) {
                fut.onNodeLeft();
            } catch (IgniteCheckedException e) {
                if (!cctx.kernalContext().isStopping()) {
                    if (msgLog.isDebugEnabled()) {
                        msgLog.debug("DHT prepare fut, failed to send request near [txId=" + tx.nearXidVersion() + ", dhtTxId=" + tx.xidVersion() + ", node=" + nearMapping.primary().id() + ']');
                    }
                    fut.onResult(e);
                } else {
                    if (msgLog.isDebugEnabled()) {
                        msgLog.debug("DHT prepare fut, failed to send request near, ignore [txId=" + tx.nearXidVersion() + ", dhtTxId=" + tx.xidVersion() + ", node=" + nearMapping.primary().id() + ", err=" + e + ']');
                    }
                }
            }
        }
    }
}
Also used : ClusterNode(org.apache.ignite.cluster.ClusterNode) IgniteTxEntry(org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry) GridDistributedTxMapping(org.apache.ignite.internal.processors.cache.distributed.GridDistributedTxMapping) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) GridCacheEntryRemovedException(org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException) GridCacheMvccCandidate(org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate) ClusterTopologyCheckedException(org.apache.ignite.internal.cluster.ClusterTopologyCheckedException)

Example 40 with IgniteTxEntry

use of org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry in project ignite by apache.

the class GridDhtTxPrepareFuture method onEntriesLocked.

/**
 */
private void onEntriesLocked() {
    ret = new GridCacheReturn(null, tx.localResult(), true, null, true);
    for (IgniteTxEntry writeEntry : req.writes()) {
        IgniteTxEntry txEntry = tx.entry(writeEntry.txKey());
        assert txEntry != null : writeEntry;
        GridCacheContext cacheCtx = txEntry.context();
        GridCacheEntryEx cached = txEntry.cached();
        ExpiryPolicy expiry = cacheCtx.expiryForTxEntry(txEntry);
        cctx.database().checkpointReadLock();
        try {
            if ((txEntry.op() == CREATE || txEntry.op() == UPDATE) && txEntry.conflictExpireTime() == CU.EXPIRE_TIME_CALCULATE) {
                if (expiry != null) {
                    cached.unswap(true);
                    Duration duration = cached.hasValue() ? expiry.getExpiryForUpdate() : expiry.getExpiryForCreation();
                    txEntry.ttl(CU.toTtl(duration));
                }
            }
            boolean hasFilters = !F.isEmptyOrNulls(txEntry.filters()) && !F.isAlwaysTrue(txEntry.filters());
            CacheObject val;
            CacheObject oldVal = null;
            boolean readOld = hasFilters || retVal || txEntry.op() == DELETE || txEntry.op() == TRANSFORM || tx.nearOnOriginatingNode() || tx.hasInterceptor();
            if (readOld) {
                boolean readThrough = !txEntry.skipStore() && (txEntry.op() == TRANSFORM || ((retVal || hasFilters) && cacheCtx.config().isLoadPreviousValue()));
                boolean evt = retVal || txEntry.op() == TRANSFORM;
                EntryProcessor entryProc = null;
                if (evt && txEntry.op() == TRANSFORM)
                    entryProc = F.first(txEntry.entryProcessors()).get1();
                final boolean keepBinary = txEntry.keepBinary();
                val = oldVal = cached.innerGet(null, tx, readThrough, /*metrics*/
                retVal, /*event*/
                evt, tx.subjectId(), entryProc, tx.resolveTaskName(), null, keepBinary);
                if (retVal || txEntry.op() == TRANSFORM) {
                    if (!F.isEmpty(txEntry.entryProcessors())) {
                        invoke = true;
                        if (txEntry.hasValue())
                            val = txEntry.value();
                        KeyCacheObject key = txEntry.key();
                        Object procRes = null;
                        Exception err = null;
                        boolean modified = false;
                        txEntry.oldValueOnPrimary(val != null);
                        for (T2<EntryProcessor<Object, Object, Object>, Object[]> t : txEntry.entryProcessors()) {
                            CacheInvokeEntry<Object, Object> invokeEntry = new CacheInvokeEntry<>(key, val, txEntry.cached().version(), keepBinary, txEntry.cached());
                            try {
                                EntryProcessor<Object, Object, Object> processor = t.get1();
                                procRes = processor.process(invokeEntry, t.get2());
                                val = cacheCtx.toCacheObject(invokeEntry.getValue(true));
                                if (// no validation for remove case
                                val != null)
                                    cacheCtx.validateKeyAndValue(key, val);
                            } catch (Exception e) {
                                err = e;
                                break;
                            }
                            modified |= invokeEntry.modified();
                        }
                        if (modified)
                            val = cacheCtx.toCacheObject(cacheCtx.unwrapTemporary(val));
                        GridCacheOperation op = modified ? (val == null ? DELETE : UPDATE) : NOOP;
                        if (op == NOOP) {
                            if (expiry != null) {
                                long ttl = CU.toTtl(expiry.getExpiryForAccess());
                                txEntry.ttl(ttl);
                                if (ttl == CU.TTL_ZERO)
                                    op = DELETE;
                            }
                        }
                        txEntry.entryProcessorCalculatedValue(new T2<>(op, op == NOOP ? null : val));
                        if (retVal) {
                            if (err != null || procRes != null)
                                ret.addEntryProcessResult(txEntry.context(), key, null, procRes, err, keepBinary);
                            else
                                ret.invokeResult(true);
                        }
                    } else if (retVal)
                        ret.value(cacheCtx, val, keepBinary);
                }
                if (hasFilters && !cacheCtx.isAll(cached, txEntry.filters())) {
                    if (expiry != null)
                        txEntry.ttl(CU.toTtl(expiry.getExpiryForAccess()));
                    txEntry.op(GridCacheOperation.NOOP);
                    if (filterFailedKeys == null)
                        filterFailedKeys = new ArrayList<>();
                    filterFailedKeys.add(cached.txKey());
                    ret.success(false);
                } else
                    ret.success(txEntry.op() != DELETE || cached.hasValue());
            }
            // Send old value in case if rebalancing is not finished.
            final boolean sndOldVal = !cacheCtx.isLocal() && !cacheCtx.topology().rebalanceFinished(tx.topologyVersion());
            if (sndOldVal) {
                if (oldVal == null && !readOld) {
                    oldVal = cached.innerGet(null, tx, /*readThrough*/
                    false, /*metrics*/
                    false, /*event*/
                    false, /*subjectId*/
                    tx.subjectId(), /*transformClo*/
                    null, /*taskName*/
                    null, /*expiryPlc*/
                    null, /*keepBinary*/
                    true);
                }
                if (oldVal != null)
                    oldVal.prepareMarshal(cacheCtx.cacheObjectContext());
                txEntry.oldValue(oldVal);
            }
        } catch (IgniteCheckedException e) {
            U.error(log, "Failed to get result value for cache entry: " + cached, e);
        } catch (GridCacheEntryRemovedException e) {
            assert false : "Got entry removed exception while holding transactional lock on entry [e=" + e + ", cached=" + cached + ']';
        } finally {
            cctx.database().checkpointReadUnlock();
        }
    }
}
Also used : IgniteTxEntry(org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry) GridCacheContext(org.apache.ignite.internal.processors.cache.GridCacheContext) GridCacheReturn(org.apache.ignite.internal.processors.cache.GridCacheReturn) ArrayList(java.util.ArrayList) Duration(javax.cache.expiry.Duration) IgniteTxTimeoutCheckedException(org.apache.ignite.internal.transactions.IgniteTxTimeoutCheckedException) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) GridCacheEntryRemovedException(org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException) IgniteInterruptedException(org.apache.ignite.IgniteInterruptedException) IgniteTxHeuristicCheckedException(org.apache.ignite.internal.transactions.IgniteTxHeuristicCheckedException) IgniteFutureCancelledException(org.apache.ignite.lang.IgniteFutureCancelledException) ClusterTopologyCheckedException(org.apache.ignite.internal.cluster.ClusterTopologyCheckedException) IgniteTxOptimisticCheckedException(org.apache.ignite.internal.transactions.IgniteTxOptimisticCheckedException) GridCacheEntryEx(org.apache.ignite.internal.processors.cache.GridCacheEntryEx) EntryProcessor(javax.cache.processor.EntryProcessor) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) CacheInvokeEntry(org.apache.ignite.internal.processors.cache.CacheInvokeEntry) ExpiryPolicy(javax.cache.expiry.ExpiryPolicy) CacheObject(org.apache.ignite.internal.processors.cache.CacheObject) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) GridCacheEntryRemovedException(org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException) CacheObject(org.apache.ignite.internal.processors.cache.CacheObject) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) GridCacheOperation(org.apache.ignite.internal.processors.cache.GridCacheOperation) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject)

Aggregations

IgniteTxEntry (org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry)51 IgniteCheckedException (org.apache.ignite.IgniteCheckedException)23 GridCacheEntryRemovedException (org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException)20 GridCacheEntryEx (org.apache.ignite.internal.processors.cache.GridCacheEntryEx)14 IgniteTxKey (org.apache.ignite.internal.processors.cache.transactions.IgniteTxKey)14 GridCacheVersion (org.apache.ignite.internal.processors.cache.version.GridCacheVersion)14 CacheObject (org.apache.ignite.internal.processors.cache.CacheObject)12 KeyCacheObject (org.apache.ignite.internal.processors.cache.KeyCacheObject)12 GridDistributedTxMapping (org.apache.ignite.internal.processors.cache.distributed.GridDistributedTxMapping)11 ClusterNode (org.apache.ignite.cluster.ClusterNode)10 ClusterTopologyCheckedException (org.apache.ignite.internal.cluster.ClusterTopologyCheckedException)10 GridCacheContext (org.apache.ignite.internal.processors.cache.GridCacheContext)10 AffinityTopologyVersion (org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion)9 IgniteTxTimeoutCheckedException (org.apache.ignite.internal.transactions.IgniteTxTimeoutCheckedException)8 ArrayList (java.util.ArrayList)6 HashMap (java.util.HashMap)6 Map (java.util.Map)6 IgniteTxOptimisticCheckedException (org.apache.ignite.internal.transactions.IgniteTxOptimisticCheckedException)6 Collection (java.util.Collection)5 GridCacheMvccCandidate (org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate)5