Search in sources :

Example 31 with GridCacheEntryRemovedException

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

the class GridNearOptimisticSerializableTxPrepareFuture method onOwnerChanged.

/**
 * {@inheritDoc}
 */
@Override
public boolean onOwnerChanged(GridCacheEntryEx entry, GridCacheMvccCandidate owner) {
    if (log.isDebugEnabled())
        log.debug("Transaction future received owner changed callback: " + entry);
    if ((entry.context().isNear() || entry.context().isLocal()) && owner != null) {
        IgniteTxEntry txEntry = tx.entry(entry.txKey());
        if (txEntry != null) {
            if (entry.context().isLocal()) {
                GridCacheVersion serReadVer = txEntry.entryReadVersion();
                if (serReadVer != null) {
                    GridCacheContext ctx = entry.context();
                    while (true) {
                        try {
                            if (!entry.checkSerializableReadVersion(serReadVer)) {
                                Object key = entry.key().value(ctx.cacheObjectContext(), false);
                                IgniteTxOptimisticCheckedException err0 = new IgniteTxOptimisticCheckedException(S.toString("Failed to prepare transaction, read/write conflict", "key", key, true, "cache", ctx.name(), false));
                                ERR_UPD.compareAndSet(this, null, err0);
                            }
                            break;
                        } catch (GridCacheEntryRemovedException ignored) {
                            entry = ctx.cache().entryEx(entry.key(), tx.topologyVersion());
                            txEntry.cached(entry);
                        }
                    }
                }
            }
            if (keyLockFut != null)
                keyLockFut.onKeyLocked(entry.txKey());
            return true;
        }
    }
    return false;
}
Also used : IgniteTxEntry(org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry) GridCacheVersion(org.apache.ignite.internal.processors.cache.version.GridCacheVersion) GridCacheContext(org.apache.ignite.internal.processors.cache.GridCacheContext) GridCacheEntryRemovedException(org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException) IgniteTxOptimisticCheckedException(org.apache.ignite.internal.transactions.IgniteTxOptimisticCheckedException)

Example 32 with GridCacheEntryRemovedException

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

the class GridNearOptimisticTxPrepareFuture method map.

/**
 * @param entry Transaction entry.
 * @param topVer Topology version.
 * @param cur Current mapping.
 * @param topLocked {@code True} if thread already acquired lock preventing topology change.
 * @param remap Remap flag.
 * @return Mapping.
 */
private GridDistributedTxMapping map(IgniteTxEntry entry, AffinityTopologyVersion topVer, @Nullable GridDistributedTxMapping cur, boolean topLocked, boolean remap) {
    GridCacheContext cacheCtx = entry.context();
    List<ClusterNode> nodes;
    GridCacheEntryEx cached0 = entry.cached();
    if (cached0.isDht())
        nodes = cacheCtx.topology().nodes(cached0.partition(), topVer);
    else
        nodes = cacheCtx.isLocal() ? cacheCtx.affinity().nodesByKey(entry.key(), topVer) : cacheCtx.topology().nodes(cacheCtx.affinity().partition(entry.key()), topVer);
    if (F.isEmpty(nodes)) {
        ClusterTopologyServerNotFoundException e = 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 + ']');
        onDone(e);
        return null;
    }
    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 (cacheCtx.isNear() || cacheCtx.isLocal()) {
        if (entry.explicitVersion() == null && !remap) {
            if (keyLockFut == null) {
                keyLockFut = new KeyLockFuture();
                add(keyLockFut);
            }
            keyLockFut.addLockKey(entry.txKey());
        }
    }
    if (cur == null || !cur.primary().id().equals(primary.id()) || (primary.isLocal() && cur.hasNearCacheEntries() != cacheCtx.isNear())) {
        boolean clientFirst = cur == null && !topLocked && cctx.kernalContext().clientNode();
        cur = new GridDistributedTxMapping(primary);
        cur.clientFirst(clientFirst);
    }
    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));
            }
        }
    }
    return cur;
}
Also used : ClusterNode(org.apache.ignite.cluster.ClusterNode) GridCacheEntryEx(org.apache.ignite.internal.processors.cache.GridCacheEntryEx) GridCacheContext(org.apache.ignite.internal.processors.cache.GridCacheContext) ClusterTopologyServerNotFoundException(org.apache.ignite.internal.cluster.ClusterTopologyServerNotFoundException) GridDistributedTxMapping(org.apache.ignite.internal.processors.cache.distributed.GridDistributedTxMapping) GridCacheEntryRemovedException(org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException)

Example 33 with GridCacheEntryRemovedException

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

the class IgniteTxLocalAdapter method userCommit.

/**
 * {@inheritDoc}
 */
@SuppressWarnings({ "CatchGenericClass" })
@Override
public void userCommit() throws IgniteCheckedException {
    TransactionState state = state();
    if (state != COMMITTING) {
        if (remainingTime() == -1)
            throw new IgniteTxTimeoutCheckedException("Transaction timed out: " + this);
        setRollbackOnly();
        throw new IgniteCheckedException("Invalid transaction state for commit [state=" + state + ", tx=" + this + ']');
    }
    checkValid();
    Collection<IgniteTxEntry> commitEntries = (near() || cctx.snapshot().needTxReadLogging()) ? allEntries() : writeEntries();
    boolean empty = F.isEmpty(commitEntries);
    // locks on backup nodes.
    if (!empty || colocated())
        cctx.tm().addCommittedTx(this);
    if (!empty) {
        batchStoreCommit(writeEntries());
        WALPointer ptr = null;
        cctx.database().checkpointReadLock();
        try {
            cctx.tm().txContext(this);
            AffinityTopologyVersion topVer = topologyVersion();
            /*
                 * Commit to cache. Note that for 'near' transaction we loop through all the entries.
                 */
            for (IgniteTxEntry txEntry : commitEntries) {
                GridCacheContext cacheCtx = txEntry.context();
                GridDrType drType = cacheCtx.isDrEnabled() ? DR_PRIMARY : DR_NONE;
                UUID nodeId = txEntry.nodeId() == null ? this.nodeId : txEntry.nodeId();
                try {
                    while (true) {
                        try {
                            GridCacheEntryEx cached = txEntry.cached();
                            // transaction manager to make sure locks are held.
                            if (!evictNearEntry(txEntry, false)) {
                                if (cacheCtx.isNear() && cacheCtx.dr().receiveEnabled()) {
                                    cached.markObsolete(xidVer);
                                    break;
                                }
                                if (cached.detached())
                                    break;
                                GridCacheEntryEx nearCached = null;
                                boolean metrics = true;
                                if (updateNearCache(cacheCtx, txEntry.key(), topVer))
                                    nearCached = cacheCtx.dht().near().peekEx(txEntry.key());
                                else if (cacheCtx.isNear() && txEntry.locallyMapped())
                                    metrics = false;
                                boolean evt = !isNearLocallyMapped(txEntry, false);
                                if (!F.isEmpty(txEntry.entryProcessors()) || !F.isEmpty(txEntry.filters()))
                                    txEntry.cached().unswap(false);
                                IgniteBiTuple<GridCacheOperation, CacheObject> res = applyTransformClosures(txEntry, true, null);
                                GridCacheVersion dhtVer = null;
                                // backup remote transaction completes.
                                if (cacheCtx.isNear()) {
                                    if (txEntry.op() == CREATE || txEntry.op() == UPDATE || txEntry.op() == DELETE || txEntry.op() == TRANSFORM)
                                        dhtVer = txEntry.dhtVersion();
                                    if ((txEntry.op() == CREATE || txEntry.op() == UPDATE) && txEntry.conflictExpireTime() == CU.EXPIRE_TIME_CALCULATE) {
                                        ExpiryPolicy expiry = cacheCtx.expiryForTxEntry(txEntry);
                                        if (expiry != null) {
                                            txEntry.cached().unswap(false);
                                            Duration duration = cached.hasValue() ? expiry.getExpiryForUpdate() : expiry.getExpiryForCreation();
                                            txEntry.ttl(CU.toTtl(duration));
                                        }
                                    }
                                }
                                GridCacheOperation op = res.get1();
                                CacheObject val = res.get2();
                                // Deal with conflicts.
                                GridCacheVersion explicitVer = txEntry.conflictVersion() != null ? txEntry.conflictVersion() : writeVersion();
                                if ((op == CREATE || op == UPDATE) && txEntry.conflictExpireTime() == CU.EXPIRE_TIME_CALCULATE) {
                                    ExpiryPolicy expiry = cacheCtx.expiryForTxEntry(txEntry);
                                    if (expiry != null) {
                                        Duration duration = cached.hasValue() ? expiry.getExpiryForUpdate() : expiry.getExpiryForCreation();
                                        long ttl = CU.toTtl(duration);
                                        txEntry.ttl(ttl);
                                        if (ttl == CU.TTL_ZERO)
                                            op = DELETE;
                                    }
                                }
                                boolean conflictNeedResolve = cacheCtx.conflictNeedResolve();
                                GridCacheVersionConflictContext<?, ?> conflictCtx = null;
                                if (conflictNeedResolve) {
                                    IgniteBiTuple<GridCacheOperation, GridCacheVersionConflictContext> conflictRes = conflictResolve(op, txEntry, val, explicitVer, cached);
                                    assert conflictRes != null;
                                    conflictCtx = conflictRes.get2();
                                    if (conflictCtx.isUseOld())
                                        op = NOOP;
                                    else if (conflictCtx.isUseNew()) {
                                        txEntry.ttl(conflictCtx.ttl());
                                        txEntry.conflictExpireTime(conflictCtx.expireTime());
                                    } else {
                                        assert conflictCtx.isMerge();
                                        op = conflictRes.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;
                                if (sndTransformedVals || conflictNeedResolve) {
                                    assert sndTransformedVals && cacheCtx.isReplicated() || conflictNeedResolve;
                                    txEntry.value(val, true, false);
                                    txEntry.op(op);
                                    txEntry.entryProcessors(null);
                                    txEntry.conflictVersion(explicitVer);
                                }
                                if (dhtVer == null)
                                    dhtVer = explicitVer != null ? explicitVer : writeVersion();
                                if (op == CREATE || op == UPDATE) {
                                    assert val != null : txEntry;
                                    GridCacheUpdateTxResult updRes = cached.innerSet(this, eventNodeId(), txEntry.nodeId(), val, false, false, txEntry.ttl(), evt, metrics, txEntry.keepBinary(), txEntry.hasOldValue(), txEntry.oldValue(), topVer, null, cached.detached() ? DR_NONE : drType, txEntry.conflictExpireTime(), cached.isNear() ? null : explicitVer, CU.subjectId(this, cctx), resolveTaskName(), dhtVer, null);
                                    if (updRes.success())
                                        txEntry.updateCounter(updRes.updatePartitionCounter());
                                    if (updRes.loggedPointer() != null)
                                        ptr = updRes.loggedPointer();
                                    if (nearCached != null && updRes.success()) {
                                        nearCached.innerSet(null, eventNodeId(), nodeId, val, false, false, txEntry.ttl(), false, metrics, txEntry.keepBinary(), txEntry.hasOldValue(), txEntry.oldValue(), topVer, CU.empty0(), DR_NONE, txEntry.conflictExpireTime(), null, CU.subjectId(this, cctx), resolveTaskName(), dhtVer, null);
                                    }
                                } else if (op == DELETE) {
                                    GridCacheUpdateTxResult updRes = cached.innerRemove(this, eventNodeId(), txEntry.nodeId(), false, evt, metrics, txEntry.keepBinary(), txEntry.hasOldValue(), txEntry.oldValue(), topVer, null, cached.detached() ? DR_NONE : drType, cached.isNear() ? null : explicitVer, CU.subjectId(this, cctx), resolveTaskName(), dhtVer, null);
                                    if (updRes.success())
                                        txEntry.updateCounter(updRes.updatePartitionCounter());
                                    if (updRes.loggedPointer() != null)
                                        ptr = updRes.loggedPointer();
                                    if (nearCached != null && updRes.success()) {
                                        nearCached.innerRemove(null, eventNodeId(), nodeId, false, false, metrics, txEntry.keepBinary(), txEntry.hasOldValue(), txEntry.oldValue(), topVer, CU.empty0(), DR_NONE, null, CU.subjectId(this, cctx), resolveTaskName(), dhtVer, null);
                                    }
                                } else if (op == RELOAD) {
                                    cached.innerReload();
                                    if (nearCached != null)
                                        nearCached.innerReload();
                                } else if (op == READ) {
                                    CacheGroupContext grp = cacheCtx.group();
                                    if (grp.persistenceEnabled() && grp.walEnabled() && cctx.snapshot().needTxReadLogging()) {
                                        ptr = cctx.wal().log(new DataRecord(new DataEntry(cacheCtx.cacheId(), txEntry.key(), val, op, nearXidVersion(), writeVersion(), 0, txEntry.key().partition(), txEntry.updateCounter())));
                                    }
                                    ExpiryPolicy expiry = cacheCtx.expiryForTxEntry(txEntry);
                                    if (expiry != null) {
                                        Duration duration = expiry.getExpiryForAccess();
                                        if (duration != null)
                                            cached.updateTtl(null, CU.toTtl(duration));
                                    }
                                    if (log.isDebugEnabled())
                                        log.debug("Ignoring READ entry when committing: " + txEntry);
                                } else {
                                    assert ownsLock(txEntry.cached()) : "Transaction does not own lock for group lock entry during  commit [tx=" + this + ", txEntry=" + txEntry + ']';
                                    if (conflictCtx == null || !conflictCtx.isUseOld()) {
                                        if (txEntry.ttl() != CU.TTL_NOT_CHANGED)
                                            cached.updateTtl(null, txEntry.ttl());
                                    }
                                    if (log.isDebugEnabled())
                                        log.debug("Ignoring NOOP entry when committing: " + txEntry);
                                }
                            }
                            // if an entry is obsolete).
                            if (txEntry.op() != READ)
                                checkCommitLocks(cached);
                            // Break out of while loop.
                            break;
                        }// If entry cached within transaction got removed.
                         catch (GridCacheEntryRemovedException ignored) {
                            if (log.isDebugEnabled())
                                log.debug("Got removed entry during transaction commit (will retry): " + txEntry);
                            txEntry.cached(entryEx(cacheCtx, txEntry.txKey(), topologyVersion()));
                        }
                    }
                } catch (Throwable ex) {
                    // We are about to initiate transaction rollback when tx has started to committing.
                    // Need to remove version from committed list.
                    cctx.tm().removeCommittedTx(this);
                    if (X.hasCause(ex, GridCacheIndexUpdateException.class) && cacheCtx.cache().isMongoDataCache()) {
                        if (log.isDebugEnabled())
                            log.debug("Failed to update mongo document index (transaction entry will " + "be ignored): " + txEntry);
                        // Set operation to NOOP.
                        txEntry.op(NOOP);
                        errorWhenCommitting();
                        throw ex;
                    } else {
                        boolean nodeStopping = X.hasCause(ex, NodeStoppingException.class);
                        IgniteCheckedException err = new IgniteTxHeuristicCheckedException("Failed to locally write to cache " + "(all transaction entries will be invalidated, however there was a window when " + "entries for this transaction were visible to others): " + this, ex);
                        if (nodeStopping) {
                            U.warn(log, "Failed to commit transaction, node is stopping " + "[tx=" + this + ", err=" + ex + ']');
                        } else
                            U.error(log, "Heuristic transaction failure.", err);
                        COMMIT_ERR_UPD.compareAndSet(this, null, err);
                        state(UNKNOWN);
                        try {
                            // Courtesy to minimize damage.
                            uncommit(nodeStopping);
                        } catch (Throwable ex1) {
                            U.error(log, "Failed to uncommit transaction: " + this, ex1);
                            if (ex1 instanceof Error)
                                throw ex1;
                        }
                        if (ex instanceof Error)
                            throw ex;
                        throw err;
                    }
                }
            }
            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();
            cctx.tm().resetContext();
        }
    }
    // Do not unlock transaction entries if one-phase commit.
    if (!onePhaseCommit()) {
        if (DONE_FLAG_UPD.compareAndSet(this, 0, 1)) {
            // Unlock all locks.
            cctx.tm().commitTx(this);
            boolean needsCompletedVersions = needsCompletedVersions();
            assert !needsCompletedVersions || completedBase != null;
            assert !needsCompletedVersions || committedVers != null;
            assert !needsCompletedVersions || rolledbackVers != null;
        }
    }
}
Also used : TransactionState(org.apache.ignite.transactions.TransactionState) NodeStoppingException(org.apache.ignite.internal.NodeStoppingException) 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) IgniteCacheExpiryPolicy(org.apache.ignite.internal.processors.cache.IgniteCacheExpiryPolicy) ExpiryPolicy(javax.cache.expiry.ExpiryPolicy) 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) GridCacheContext(org.apache.ignite.internal.processors.cache.GridCacheContext) AffinityTopologyVersion(org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion) Duration(javax.cache.expiry.Duration) GridCacheVersionConflictContext(org.apache.ignite.internal.processors.cache.version.GridCacheVersionConflictContext) GridCacheEntryEx(org.apache.ignite.internal.processors.cache.GridCacheEntryEx) GridDrType(org.apache.ignite.internal.processors.dr.GridDrType) GridCacheUpdateTxResult(org.apache.ignite.internal.processors.cache.GridCacheUpdateTxResult) IgniteTxTimeoutCheckedException(org.apache.ignite.internal.transactions.IgniteTxTimeoutCheckedException) GridCacheOperation(org.apache.ignite.internal.processors.cache.GridCacheOperation) CacheGroupContext(org.apache.ignite.internal.processors.cache.CacheGroupContext) StorageException(org.apache.ignite.internal.pagemem.wal.StorageException)

Example 34 with GridCacheEntryRemovedException

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

the class IgniteTxLocalAdapter method addEntry.

/**
 * @param op Cache operation.
 * @param val Value.
 * @param expiryPlc Explicitly specified expiry policy.
 * @param invokeArgs Optional arguments for EntryProcessor.
 * @param entryProcessor Entry processor.
 * @param entry Cache entry.
 * @param filter Filter.
 * @param filtersSet {@code True} if filter should be marked as set.
 * @param drTtl DR TTL (if any).
 * @param drExpireTime DR expire time (if any).
 * @param drVer DR version.
 * @param skipStore Skip store flag.
 * @return Transaction entry.
 */
protected final IgniteTxEntry addEntry(GridCacheOperation op, @Nullable CacheObject val, @Nullable EntryProcessor entryProcessor, Object[] invokeArgs, GridCacheEntryEx entry, @Nullable ExpiryPolicy expiryPlc, CacheEntryPredicate[] filter, boolean filtersSet, long drTtl, long drExpireTime, @Nullable GridCacheVersion drVer, boolean skipStore, boolean keepBinary, boolean addReader) {
    assert invokeArgs == null || op == TRANSFORM;
    IgniteTxKey key = entry.txKey();
    checkInternal(key);
    TransactionState state = state();
    assert state == TransactionState.ACTIVE || remainingTime() == -1 : "Invalid tx state for adding entry [op=" + op + ", val=" + val + ", entry=" + entry + ", filter=" + Arrays.toString(filter) + ", txCtx=" + cctx.tm().txContextVersion() + ", tx=" + this + ']';
    IgniteTxEntry old = entry(key);
    // Keep old filter if already have one (empty filter is always overridden).
    if (!filtersSet || !F.isEmptyOrNulls(filter)) {
        // Replace filter if previous filter failed.
        if (old != null && old.filtersSet())
            filter = old.filters();
    }
    IgniteTxEntry txEntry;
    if (old != null) {
        if (entryProcessor != null) {
            assert val == null;
            assert op == TRANSFORM;
            // Will change the op.
            old.addEntryProcessor(entryProcessor, invokeArgs);
        } else {
            assert old.op() != TRANSFORM;
            old.op(op);
            old.value(val, op == CREATE || op == UPDATE || op == DELETE, op == READ);
        }
        // Keep old ttl value.
        old.cached(entry);
        old.filters(filter);
        // Keep old skipStore and keepBinary flags.
        old.skipStore(skipStore);
        old.keepBinary(keepBinary);
        // Update ttl if specified.
        if (drTtl >= 0L) {
            assert drExpireTime >= 0L;
            entryTtlDr(key, drTtl, drExpireTime);
        } else
            entryExpiry(key, expiryPlc);
        txEntry = old;
        if (log.isDebugEnabled())
            log.debug("Updated transaction entry: " + txEntry);
    } else {
        boolean hasDrTtl = drTtl >= 0;
        txEntry = new IgniteTxEntry(entry.context(), this, op, val, EntryProcessorResourceInjectorProxy.wrap(cctx.kernalContext(), entryProcessor), invokeArgs, hasDrTtl ? drTtl : -1L, entry, filter, drVer, skipStore, keepBinary, addReader);
        txEntry.conflictExpireTime(drExpireTime);
        if (!hasDrTtl)
            txEntry.expiry(expiryPlc);
        txState.addEntry(txEntry);
        if (log.isDebugEnabled())
            log.debug("Created transaction entry: " + txEntry);
    }
    txEntry.filtersSet(filtersSet);
    while (true) {
        try {
            updateExplicitVersion(txEntry, entry);
            return txEntry;
        } catch (GridCacheEntryRemovedException ignore) {
            if (log.isDebugEnabled())
                log.debug("Got removed entry in transaction newEntry method (will retry): " + entry);
            entry = entryEx(entry.context(), txEntry.txKey(), topologyVersion());
            txEntry.cached(entry);
        }
    }
}
Also used : TransactionState(org.apache.ignite.transactions.TransactionState) GridCacheEntryRemovedException(org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException)

Example 35 with GridCacheEntryRemovedException

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

the class IgniteTxLocalAdapter method postLockWrite.

/**
 * Post lock processing for put or remove.
 *
 * @param cacheCtx Context.
 * @param keys Keys.
 * @param ret Return value.
 * @param rmv {@code True} if remove.
 * @param retval Flag to return value or not.
 * @param read {@code True} if read.
 * @param accessTtl TTL for read operation.
 * @param filter Filter to check entries.
 * @throws IgniteCheckedException If error.
 * @param computeInvoke If {@code true} computes return value for invoke operation.
 */
@SuppressWarnings("unchecked")
protected final void postLockWrite(GridCacheContext cacheCtx, Iterable<KeyCacheObject> keys, GridCacheReturn ret, boolean rmv, boolean retval, boolean read, long accessTtl, CacheEntryPredicate[] filter, boolean computeInvoke) throws IgniteCheckedException {
    for (KeyCacheObject k : keys) {
        IgniteTxEntry txEntry = entry(cacheCtx.txKey(k));
        if (txEntry == null)
            throw new IgniteCheckedException("Transaction entry is null (most likely collection of keys passed into cache " + "operation was changed before operation completed) [missingKey=" + k + ", tx=" + this + ']');
        while (true) {
            GridCacheEntryEx cached = txEntry.cached();
            try {
                assert cached.detached() || cached.lockedByThread(threadId) || isRollbackOnly() : "Transaction lock is not acquired [entry=" + cached + ", tx=" + this + ", nodeId=" + cctx.localNodeId() + ", threadId=" + threadId + ']';
                if (log.isDebugEnabled())
                    log.debug("Post lock write entry: " + cached);
                CacheObject v = txEntry.previousValue();
                boolean hasPrevVal = txEntry.hasPreviousValue();
                if (onePhaseCommit())
                    filter = txEntry.filters();
                // If we have user-passed filter, we must read value into entry for peek().
                if (!F.isEmptyOrNulls(filter) && !F.isAlwaysTrue(filter))
                    retval = true;
                boolean invoke = txEntry.op() == TRANSFORM;
                if (retval || invoke) {
                    if (!cacheCtx.isNear()) {
                        if (!hasPrevVal) {
                            // For non-local cache should read from store after lock on primary.
                            boolean readThrough = cacheCtx.isLocal() && (invoke || cacheCtx.loadPreviousValue()) && !txEntry.skipStore();
                            v = cached.innerGet(null, this, readThrough, /*metrics*/
                            !invoke, /*event*/
                            !invoke && !dht(), CU.subjectId(this, cctx), null, resolveTaskName(), null, txEntry.keepBinary());
                        }
                    } else {
                        if (!hasPrevVal)
                            v = cached.rawGet();
                    }
                    if (txEntry.op() == TRANSFORM) {
                        if (computeInvoke) {
                            GridCacheVersion ver;
                            try {
                                ver = cached.version();
                            } catch (GridCacheEntryRemovedException e) {
                                assert optimistic() : txEntry;
                                if (log.isDebugEnabled())
                                    log.debug("Failed to get entry version: [msg=" + e.getMessage() + ']');
                                ver = null;
                            }
                            addInvokeResult(txEntry, v, ret, ver);
                        }
                    } else
                        ret.value(cacheCtx, v, txEntry.keepBinary());
                }
                boolean pass = F.isEmpty(filter) || cacheCtx.isAll(cached, filter);
                // For remove operation we return true only if we are removing s/t,
                // i.e. cached value is not null.
                ret.success(pass && (!retval ? !rmv || cached.hasValue() || v != null : !rmv || v != null));
                if (onePhaseCommit())
                    txEntry.filtersPassed(pass);
                boolean updateTtl = read;
                if (pass) {
                    txEntry.markValid();
                    if (log.isDebugEnabled())
                        log.debug("Filter passed in post lock for key: " + k);
                } else {
                    // Revert operation to previous. (if no - NOOP, so entry will be unlocked).
                    txEntry.setAndMarkValid(txEntry.previousOperation(), cacheCtx.toCacheObject(ret.value()));
                    txEntry.filters(CU.empty0());
                    txEntry.filtersSet(false);
                    updateTtl = !cacheCtx.putIfAbsentFilter(filter);
                }
                if (updateTtl) {
                    if (!read) {
                        ExpiryPolicy expiryPlc = cacheCtx.expiryForTxEntry(txEntry);
                        if (expiryPlc != null)
                            txEntry.ttl(CU.toTtl(expiryPlc.getExpiryForAccess()));
                    } else
                        txEntry.ttl(accessTtl);
                }
                // While.
                break;
            }// If entry cached within transaction got removed before lock.
             catch (GridCacheEntryRemovedException ignore) {
                if (log.isDebugEnabled())
                    log.debug("Got removed entry in putAllAsync method (will retry): " + cached);
                txEntry.cached(entryEx(cached.context(), txEntry.txKey(), topologyVersion()));
            }
        }
    }
}
Also used : GridCacheEntryEx(org.apache.ignite.internal.processors.cache.GridCacheEntryEx) GridCacheVersion(org.apache.ignite.internal.processors.cache.version.GridCacheVersion) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) IgniteCacheExpiryPolicy(org.apache.ignite.internal.processors.cache.IgniteCacheExpiryPolicy) ExpiryPolicy(javax.cache.expiry.ExpiryPolicy) GridCacheEntryRemovedException(org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException) CacheObject(org.apache.ignite.internal.processors.cache.CacheObject) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject)

Aggregations

GridCacheEntryRemovedException (org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException)84 KeyCacheObject (org.apache.ignite.internal.processors.cache.KeyCacheObject)56 IgniteCheckedException (org.apache.ignite.IgniteCheckedException)50 CacheObject (org.apache.ignite.internal.processors.cache.CacheObject)40 GridCacheEntryEx (org.apache.ignite.internal.processors.cache.GridCacheEntryEx)40 GridCacheVersion (org.apache.ignite.internal.processors.cache.version.GridCacheVersion)40 ClusterNode (org.apache.ignite.cluster.ClusterNode)19 GridCacheContext (org.apache.ignite.internal.processors.cache.GridCacheContext)18 IgniteTxEntry (org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry)18 GridDhtInvalidPartitionException (org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtInvalidPartitionException)17 ClusterTopologyCheckedException (org.apache.ignite.internal.cluster.ClusterTopologyCheckedException)16 AffinityTopologyVersion (org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion)16 ArrayList (java.util.ArrayList)14 EntryGetResult (org.apache.ignite.internal.processors.cache.EntryGetResult)14 GridCacheOperation (org.apache.ignite.internal.processors.cache.GridCacheOperation)13 GridDhtCacheEntry (org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheEntry)12 IgniteTxKey (org.apache.ignite.internal.processors.cache.transactions.IgniteTxKey)12 Map (java.util.Map)10 GridDistributedCacheEntry (org.apache.ignite.internal.processors.cache.distributed.GridDistributedCacheEntry)10 GridTimeoutObject (org.apache.ignite.internal.processors.timeout.GridTimeoutObject)10