Search in sources :

Example 1 with EnlistOperation

use of org.apache.ignite.internal.processors.query.EnlistOperation in project ignite by apache.

the class GridDhtTxAbstractEnlistFuture method continueLoop.

/**
 * Iterates over iterator, applies changes locally and sends it on backups.
 *
 * @param ignoreCntr {@code True} if need to ignore skip counter.
 */
private void continueLoop(boolean ignoreCntr) {
    if (isDone() || (!ignoreCntr && (SKIP_UPD.getAndIncrement(this) != 0)))
        return;
    GridDhtCacheAdapter cache = cctx.dhtCache();
    EnlistOperation op = it.operation();
    AffinityTopologyVersion topVer = tx.topologyVersionSnapshot();
    try {
        while (true) {
            int curPart = -1;
            List<ClusterNode> backups = null;
            while (hasNext0()) {
                Object cur = next0();
                KeyCacheObject key = toKey(op, cur);
                if (curPart != key.partition())
                    backups = backupNodes(curPart = key.partition());
                assert backups != null;
                if (!ensureFreeSlot(key, backups)) {
                    // Can't advance further at the moment.
                    peek = cur;
                    it.beforeDetach();
                    break;
                }
                GridDhtCacheEntry entry = cache.entryExx(key);
                if (log.isDebugEnabled())
                    log.debug("Adding entry: " + entry);
                assert !entry.detached();
                CacheObject val = op.isDeleteOrLock() || op.isInvoke() ? null : cctx.toCacheObject(((IgniteBiTuple) cur).getValue());
                GridInvokeValue invokeVal = null;
                EntryProcessor entryProc = null;
                Object[] invokeArgs = null;
                if (op.isInvoke()) {
                    assert needResult();
                    invokeVal = (GridInvokeValue) ((IgniteBiTuple) cur).getValue();
                    entryProc = invokeVal.entryProcessor();
                    invokeArgs = invokeVal.invokeArgs();
                }
                assert entryProc != null || !op.isInvoke();
                boolean needOldVal = tx.txState().useMvccCaching(cctx.cacheId());
                GridCacheUpdateTxResult res;
                while (true) {
                    cctx.shared().database().checkpointReadLock();
                    try {
                        switch(op) {
                            case DELETE:
                                res = entry.mvccRemove(tx, cctx.localNodeId(), topVer, mvccSnapshot, isMoving(key.partition(), backups), needOldVal, filter, needResult());
                                break;
                            case INSERT:
                            case TRANSFORM:
                            case UPSERT:
                            case UPDATE:
                                res = entry.mvccSet(tx, cctx.localNodeId(), val, entryProc, invokeArgs, 0, topVer, mvccSnapshot, op.cacheOperation(), isMoving(key.partition(), backups), op.noCreate(), needOldVal, filter, needResult(), keepBinary);
                                break;
                            case LOCK:
                                res = entry.mvccLock(tx, mvccSnapshot);
                                break;
                            default:
                                throw new IgniteSQLException("Cannot acquire lock for operation [op= " + op + "]" + "Operation is unsupported at the moment ", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
                        }
                        break;
                    } catch (GridCacheEntryRemovedException ignored) {
                        entry = cache.entryExx(entry.key(), topVer);
                    } finally {
                        cctx.shared().database().checkpointReadUnlock();
                    }
                }
                IgniteInternalFuture<GridCacheUpdateTxResult> updateFut = res.updateFuture();
                final Message val0 = invokeVal != null ? invokeVal : val;
                if (updateFut != null) {
                    if (updateFut.isDone())
                        res = updateFut.get();
                    else {
                        GridDhtCacheEntry entry0 = entry;
                        List<ClusterNode> backups0 = backups;
                        it.beforeDetach();
                        updateFut.listen(new CI1<IgniteInternalFuture<GridCacheUpdateTxResult>>() {

                            @Override
                            public void apply(IgniteInternalFuture<GridCacheUpdateTxResult> fut) {
                                try {
                                    tx.incrementLockCounter();
                                    processEntry(entry0, op, fut.get(), val0, backups0);
                                    continueLoop(true);
                                } catch (Throwable e) {
                                    onDone(e);
                                }
                            }
                        });
                        // Can't move further. Exit loop without decrementing the counter.
                        return;
                    }
                }
                tx.incrementLockCounter();
                processEntry(entry, op, res, val0, backups);
            }
            if (!hasNext0()) {
                if (!F.isEmpty(batches)) {
                    // Flush incomplete batches.
                    // Need to skip batches for nodes where first request (contains tx info) is still in-flight.
                    // Otherwise, the regular enlist request (without tx info) may beat it to the primary node.
                    Iterator<Map.Entry<UUID, Batch>> it = batches.entrySet().iterator();
                    while (it.hasNext()) {
                        Map.Entry<UUID, Batch> e = it.next();
                        ConcurrentMap<Integer, Batch> pending0 = pending == null ? null : pending.get(e.getKey());
                        if (pending0 == null || !pending0.containsKey(FIRST_BATCH_ID)) {
                            it.remove();
                            sendBatch(e.getValue());
                        }
                    }
                }
                if (noPendingRequests()) {
                    onDone(result0());
                    return;
                }
            }
            if (SKIP_UPD.decrementAndGet(this) == 0)
                break;
            skipCntr = 1;
        }
    } catch (Throwable e) {
        onDone(e);
        if (e instanceof Error)
            throw (Error) e;
    }
}
Also used : Message(org.apache.ignite.plugin.extensions.communication.Message) IgniteBiTuple(org.apache.ignite.lang.IgniteBiTuple) IgniteInternalFuture(org.apache.ignite.internal.IgniteInternalFuture) GridCacheEntryRemovedException(org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException) CacheObject(org.apache.ignite.internal.processors.cache.CacheObject) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) UUID(java.util.UUID) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) ClusterNode(org.apache.ignite.cluster.ClusterNode) EnlistOperation(org.apache.ignite.internal.processors.query.EnlistOperation) AffinityTopologyVersion(org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion) EntryProcessor(javax.cache.processor.EntryProcessor) GridCacheUpdateTxResult(org.apache.ignite.internal.processors.cache.GridCacheUpdateTxResult) IgniteSQLException(org.apache.ignite.internal.processors.query.IgniteSQLException) CacheObject(org.apache.ignite.internal.processors.cache.CacheObject) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) ConcurrentMap(java.util.concurrent.ConcurrentMap)

Example 2 with EnlistOperation

use of org.apache.ignite.internal.processors.query.EnlistOperation in project ignite by apache.

the class GridNearTxLocal method mvccRemoveAllAsync0.

/**
 * Internal method for remove operations in Mvcc mode.
 *
 * @param cacheCtx Cache context.
 * @param keys Keys to remove.
 * @param retval Flag indicating whether a value should be returned.
 * @param filter Filter.
 * @return Future for asynchronous remove.
 */
@SuppressWarnings("unchecked")
private <K, V> IgniteInternalFuture<GridCacheReturn> mvccRemoveAllAsync0(final GridCacheContext cacheCtx, @Nullable final Collection<? extends K> keys, final boolean retval, @Nullable final CacheEntryPredicate filter) {
    try {
        MvccUtils.requestSnapshot(this);
        beforeRemove(cacheCtx, retval, true);
    } catch (IgniteCheckedException e) {
        return new GridFinishedFuture(e);
    }
    if (F.isEmpty(keys)) {
        if (implicit()) {
            try {
                commit();
            } catch (IgniteCheckedException e) {
                return new GridFinishedFuture<>(e);
            }
        }
        return new GridFinishedFuture<>(new GridCacheReturn(localResult(), true));
    }
    init();
    Set<KeyCacheObject> enlisted = new HashSet<>(keys.size());
    try {
        for (Object key : keys) {
            if (isRollbackOnly())
                return new GridFinishedFuture<>(timedOut() ? timeoutException() : rollbackException());
            if (key == null) {
                rollback();
                throw new NullPointerException("Null key.");
            }
            KeyCacheObject cacheKey = cacheCtx.toCacheKeyObject(key);
            enlisted.add(cacheKey);
        }
    } catch (IgniteCheckedException e) {
        return new GridFinishedFuture(e);
    }
    return updateAsync(cacheCtx, new UpdateSourceIterator<KeyCacheObject>() {

        private final Iterator<KeyCacheObject> it = enlisted.iterator();

        @Override
        public EnlistOperation operation() {
            return EnlistOperation.DELETE;
        }

        @Override
        public boolean hasNextX() throws IgniteCheckedException {
            return it.hasNext();
        }

        @Override
        public KeyCacheObject nextX() throws IgniteCheckedException {
            return it.next();
        }
    }, retval, filter, remainingTime(), true);
}
Also used : GridCacheReturn(org.apache.ignite.internal.processors.cache.GridCacheReturn) EnlistOperation(org.apache.ignite.internal.processors.query.EnlistOperation) GridFinishedFuture(org.apache.ignite.internal.util.future.GridFinishedFuture) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) CacheObject(org.apache.ignite.internal.processors.cache.CacheObject) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) GridTimeoutObject(org.apache.ignite.internal.processors.timeout.GridTimeoutObject) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) HashSet(java.util.HashSet)

Example 3 with EnlistOperation

use of org.apache.ignite.internal.processors.query.EnlistOperation in project ignite by apache.

the class GridNearTxEnlistFuture method continueLoop.

/**
 * Iterate data rows and form batches.
 *
 * @param nodeId Id of node acknowledged the last batch.
 * @return Collection of newly completed batches.
 * @throws IgniteCheckedException If failed.
 */
private Collection<Batch> continueLoop(@Nullable UUID nodeId) throws IgniteCheckedException {
    if (nodeId != null)
        batches.remove(nodeId);
    // Let only one thread do the looping.
    if (isDone() || SKIP_UPD.getAndIncrement(this) != 0)
        return null;
    ArrayList<Batch> res = null;
    Batch batch = null;
    boolean flush = false;
    EnlistOperation op = it.operation();
    while (true) {
        while (hasNext0()) {
            checkCompleted();
            Object cur = next0();
            KeyCacheObject key = cctx.toCacheKeyObject(op.isDeleteOrLock() ? cur : ((IgniteBiTuple) cur).getKey());
            ClusterNode node = cctx.affinity().primaryByKey(key, topVer);
            if (node == null)
                throw new ClusterTopologyServerNotFoundException("Failed to get primary node " + "[topVer=" + topVer + ", key=" + key + ']');
            if (!sequential)
                batch = batches.get(node.id());
            else if (batch != null && !batch.node().equals(node))
                res = markReady(res, batch);
            if (batch == null)
                batches.put(node.id(), batch = new Batch(node));
            if (batch.ready()) {
                // Can't advance further at the moment.
                batch = null;
                peek = cur;
                it.beforeDetach();
                flush = true;
                break;
            }
            batch.add(op.isDeleteOrLock() ? key : cur, !node.isLocal() && isLocalBackup(op, key));
            if (batch.size() == batchSize)
                res = markReady(res, batch);
        }
        if (SKIP_UPD.decrementAndGet(this) == 0)
            break;
        skipCntr = 1;
    }
    if (flush)
        return res;
    // No data left - flush incomplete batches.
    for (Batch batch0 : batches.values()) {
        if (!batch0.ready()) {
            if (res == null)
                res = new ArrayList<>();
            batch0.ready(true);
            res.add(batch0);
        }
    }
    if (batches.isEmpty())
        onDone(this.res);
    return res;
}
Also used : ClusterNode(org.apache.ignite.cluster.ClusterNode) EnlistOperation(org.apache.ignite.internal.processors.query.EnlistOperation) IgniteBiTuple(org.apache.ignite.lang.IgniteBiTuple) ClusterTopologyServerNotFoundException(org.apache.ignite.internal.cluster.ClusterTopologyServerNotFoundException) ArrayList(java.util.ArrayList) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject)

Example 4 with EnlistOperation

use of org.apache.ignite.internal.processors.query.EnlistOperation in project ignite by apache.

the class GridNearTxQueryResultsEnlistFuture method continueLoop.

/**
 * Iterate data rows and form batches.
 *
 * @param nodeId Id of node acknowledged the last batch.
 * @return Collection of newly completed batches.
 * @throws IgniteCheckedException If failed.
 */
private Collection<Batch> continueLoop(@Nullable UUID nodeId) throws IgniteCheckedException {
    if (nodeId != null)
        batches.remove(nodeId);
    // Let only one thread do the looping.
    if (isDone() || SKIP_UPD.getAndIncrement(this) != 0)
        return null;
    ArrayList<Batch> res = null;
    Batch batch = null;
    boolean flush = false;
    EnlistOperation op = it.operation();
    while (true) {
        while (hasNext0()) {
            checkCompleted();
            Object cur = next0();
            KeyCacheObject key = cctx.toCacheKeyObject(op.isDeleteOrLock() ? cur : ((IgniteBiTuple) cur).getKey());
            ClusterNode node = cctx.affinity().primaryByPartition(key.partition(), topVer);
            if (node == null)
                throw new ClusterTopologyServerNotFoundException("Failed to get primary node " + "[topVer=" + topVer + ", key=" + key + ']');
            if (!sequential)
                batch = batches.get(node.id());
            else if (batch != null && !batch.node().equals(node))
                res = markReady(res, batch);
            if (batch == null)
                batches.put(node.id(), batch = new Batch(node));
            if (batch.ready()) {
                // Can't advance further at the moment.
                batch = null;
                peek = cur;
                it.beforeDetach();
                flush = true;
                break;
            }
            batch.add(op.isDeleteOrLock() ? key : cur, !node.isLocal() && isLocalBackup(op, key));
            if (batch.size() == batchSize)
                res = markReady(res, batch);
        }
        if (SKIP_UPD.decrementAndGet(this) == 0)
            break;
        skipCntr = 1;
    }
    if (flush)
        return res;
    // No data left - flush incomplete batches.
    for (Batch batch0 : batches.values()) {
        if (!batch0.ready()) {
            if (res == null)
                res = new ArrayList<>();
            batch0.ready(true);
            res.add(batch0);
        }
    }
    if (batches.isEmpty())
        onDone(this.res);
    return res;
}
Also used : ClusterNode(org.apache.ignite.cluster.ClusterNode) EnlistOperation(org.apache.ignite.internal.processors.query.EnlistOperation) IgniteBiTuple(org.apache.ignite.lang.IgniteBiTuple) ClusterTopologyServerNotFoundException(org.apache.ignite.internal.cluster.ClusterTopologyServerNotFoundException) ArrayList(java.util.ArrayList) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject)

Example 5 with EnlistOperation

use of org.apache.ignite.internal.processors.query.EnlistOperation in project ignite by apache.

the class GridNearTxQueryResultsEnlistFuture method processBatchLocalBackupKeys.

/**
 * @param primaryId Primary node id.
 * @param rows Rows.
 * @param dhtVer Dht version assigned at primary node.
 * @param dhtFutId Dht future id assigned at primary node.
 */
private void processBatchLocalBackupKeys(UUID primaryId, List<Object> rows, GridCacheVersion dhtVer, IgniteUuid dhtFutId) {
    assert dhtVer != null;
    assert dhtFutId != null;
    EnlistOperation op = it.operation();
    assert op != EnlistOperation.LOCK;
    boolean keysOnly = op.isDeleteOrLock();
    final ArrayList<KeyCacheObject> keys = new ArrayList<>(rows.size());
    final ArrayList<Message> vals = keysOnly ? null : new ArrayList<>(rows.size());
    for (Object row : rows) {
        if (keysOnly)
            keys.add(cctx.toCacheKeyObject(row));
        else {
            keys.add(cctx.toCacheKeyObject(((IgniteBiTuple) row).getKey()));
            vals.add(cctx.toCacheObject(((IgniteBiTuple) row).getValue()));
        }
    }
    try {
        GridDhtTxRemote dhtTx = cctx.tm().tx(dhtVer);
        if (dhtTx == null) {
            dhtTx = new GridDhtTxRemote(cctx.shared(), cctx.localNodeId(), dhtFutId, primaryId, lockVer, topVer, dhtVer, null, cctx.systemTx(), cctx.ioPolicy(), PESSIMISTIC, REPEATABLE_READ, false, tx.remainingTime(), -1, SecurityUtils.securitySubjectId(cctx), tx.taskNameHash(), false, tx.label());
            dhtTx.mvccSnapshot(new MvccSnapshotWithoutTxs(mvccSnapshot.coordinatorVersion(), mvccSnapshot.counter(), MVCC_OP_COUNTER_NA, mvccSnapshot.cleanupVersion()));
            dhtTx = cctx.tm().onCreated(null, dhtTx);
            if (dhtTx == null || !cctx.tm().onStarted(dhtTx)) {
                throw new IgniteTxRollbackCheckedException("Failed to update backup " + "(transaction has been completed): " + dhtVer);
            }
        }
        cctx.tm().txHandler().mvccEnlistBatch(dhtTx, cctx, it.operation(), keys, vals, mvccSnapshot.withoutActiveTransactions(), null, -1);
    } catch (IgniteCheckedException e) {
        onDone(e);
        return;
    }
    sendNextBatches(primaryId);
}
Also used : GridDhtTxRemote(org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTxRemote) EnlistOperation(org.apache.ignite.internal.processors.query.EnlistOperation) GridCacheMessage(org.apache.ignite.internal.processors.cache.GridCacheMessage) Message(org.apache.ignite.plugin.extensions.communication.Message) IgniteBiTuple(org.apache.ignite.lang.IgniteBiTuple) ArrayList(java.util.ArrayList) IgniteTxRollbackCheckedException(org.apache.ignite.internal.transactions.IgniteTxRollbackCheckedException) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) MvccSnapshotWithoutTxs(org.apache.ignite.internal.processors.cache.mvcc.MvccSnapshotWithoutTxs) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject)

Aggregations

EnlistOperation (org.apache.ignite.internal.processors.query.EnlistOperation)8 KeyCacheObject (org.apache.ignite.internal.processors.cache.KeyCacheObject)7 IgniteBiTuple (org.apache.ignite.lang.IgniteBiTuple)7 IgniteCheckedException (org.apache.ignite.IgniteCheckedException)5 ArrayList (java.util.ArrayList)4 ClusterNode (org.apache.ignite.cluster.ClusterNode)3 ClusterTopologyServerNotFoundException (org.apache.ignite.internal.cluster.ClusterTopologyServerNotFoundException)3 CacheObject (org.apache.ignite.internal.processors.cache.CacheObject)3 Message (org.apache.ignite.plugin.extensions.communication.Message)3 EntryProcessor (javax.cache.processor.EntryProcessor)2 GridCacheMessage (org.apache.ignite.internal.processors.cache.GridCacheMessage)2 GridCacheReturn (org.apache.ignite.internal.processors.cache.GridCacheReturn)2 GridDhtTxRemote (org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTxRemote)2 MvccSnapshotWithoutTxs (org.apache.ignite.internal.processors.cache.mvcc.MvccSnapshotWithoutTxs)2 IgniteSQLException (org.apache.ignite.internal.processors.query.IgniteSQLException)2 GridTimeoutObject (org.apache.ignite.internal.processors.timeout.GridTimeoutObject)2 IgniteTxRollbackCheckedException (org.apache.ignite.internal.transactions.IgniteTxRollbackCheckedException)2 GridFinishedFuture (org.apache.ignite.internal.util.future.GridFinishedFuture)2 BatchUpdateException (java.sql.BatchUpdateException)1 SQLException (java.sql.SQLException)1