Search in sources :

Example 1 with GridNearTxRemote

use of org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxRemote in project ignite by apache.

the class IgniteTxHandler method processDhtTxPrepareRequest.

/**
 * @param nodeId Sender node ID.
 * @param req Request.
 */
private void processDhtTxPrepareRequest(final UUID nodeId, final GridDhtTxPrepareRequest req) {
    try (TraceSurroundings ignored = MTC.support(ctx.kernalContext().tracing().create(TX_PROCESS_DHT_PREPARE_REQ, MTC.span()))) {
        if (txPrepareMsgLog.isDebugEnabled()) {
            txPrepareMsgLog.debug("Received dht prepare request [txId=" + req.nearXidVersion() + ", dhtTxId=" + req.version() + ", node=" + nodeId + ']');
        }
        assert nodeId != null;
        assert req != null;
        assert req.transactionNodes() != null;
        GridDhtTxRemote dhtTx = null;
        GridNearTxRemote nearTx = null;
        GridDhtTxPrepareResponse res;
        try {
            res = new GridDhtTxPrepareResponse(req.partition(), req.version(), req.futureId(), req.miniId(), req.deployInfo() != null);
            // Start near transaction first.
            nearTx = !F.isEmpty(req.nearWrites()) ? startNearRemoteTx(ctx.deploy().globalLoader(), nodeId, req) : null;
            dhtTx = startRemoteTx(nodeId, req, res);
            // Set evicted keys from near transaction.
            if (nearTx != null)
                res.nearEvicted(nearTx.evicted());
            List<IgniteTxKey> writesCacheMissed = req.nearWritesCacheMissed();
            if (writesCacheMissed != null) {
                Collection<IgniteTxKey> evicted0 = res.nearEvicted();
                if (evicted0 != null)
                    writesCacheMissed.addAll(evicted0);
                res.nearEvicted(writesCacheMissed);
            }
            if (dhtTx != null)
                req.txState(dhtTx.txState());
            else if (nearTx != null)
                req.txState(nearTx.txState());
            if (dhtTx != null && !F.isEmpty(dhtTx.invalidPartitions()))
                res.invalidPartitionsByCacheId(dhtTx.invalidPartitions());
            if (req.onePhaseCommit()) {
                assert req.last();
                if (dhtTx != null) {
                    dhtTx.onePhaseCommit(true);
                    dhtTx.needReturnValue(req.needReturnValue());
                    finish(dhtTx, req);
                }
                if (nearTx != null) {
                    nearTx.onePhaseCommit(true);
                    finish(nearTx, req);
                }
            }
        } catch (IgniteCheckedException e) {
            if (e instanceof IgniteTxRollbackCheckedException)
                U.error(log, "Transaction was rolled back before prepare completed: " + req, e);
            else if (e instanceof IgniteTxOptimisticCheckedException) {
                if (log.isDebugEnabled())
                    log.debug("Optimistic failure for remote transaction (will rollback): " + req);
            } else
                U.error(log, "Failed to process prepare request: " + req, e);
            if (nearTx != null)
                try {
                    nearTx.rollbackRemoteTx();
                } catch (Throwable e1) {
                    e.addSuppressed(e1);
                }
            res = new GridDhtTxPrepareResponse(req.partition(), req.version(), req.futureId(), req.miniId(), e, req.deployInfo() != null);
        }
        if (req.onePhaseCommit()) {
            IgniteInternalFuture completeFut;
            IgniteInternalFuture<IgniteInternalTx> dhtFin = dhtTx == null ? null : dhtTx.done() ? null : dhtTx.finishFuture();
            final IgniteInternalFuture<IgniteInternalTx> nearFin = nearTx == null ? null : nearTx.done() ? null : nearTx.finishFuture();
            if (dhtFin != null && nearFin != null) {
                GridCompoundFuture fut = new GridCompoundFuture();
                fut.add(dhtFin);
                fut.add(nearFin);
                fut.markInitialized();
                completeFut = fut;
            } else
                completeFut = dhtFin != null ? dhtFin : nearFin;
            if (completeFut != null) {
                final GridDhtTxPrepareResponse res0 = res;
                final GridDhtTxRemote dhtTx0 = dhtTx;
                final GridNearTxRemote nearTx0 = nearTx;
                completeFut.listen(new CI1<IgniteInternalFuture<IgniteInternalTx>>() {

                    @Override
                    public void apply(IgniteInternalFuture<IgniteInternalTx> fut) {
                        sendReply(nodeId, req, res0, dhtTx0, nearTx0);
                    }
                });
            } else
                sendReply(nodeId, req, res, dhtTx, nearTx);
        } else
            sendReply(nodeId, req, res, dhtTx, nearTx);
        assert req.txState() != null || res.error() != null || (dhtTx == null && nearTx == null) : req + " tx=" + dhtTx + " nearTx=" + nearTx;
    }
}
Also used : GridDhtTxRemote(org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTxRemote) IgniteTxRollbackCheckedException(org.apache.ignite.internal.transactions.IgniteTxRollbackCheckedException) GridDhtTxPrepareResponse(org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTxPrepareResponse) IgniteInternalFuture(org.apache.ignite.internal.IgniteInternalFuture) TraceSurroundings(org.apache.ignite.internal.processors.tracing.MTC.TraceSurroundings) GridNearTxRemote(org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxRemote) IgniteTxOptimisticCheckedException(org.apache.ignite.internal.transactions.IgniteTxOptimisticCheckedException) GridCompoundFuture(org.apache.ignite.internal.util.future.GridCompoundFuture) IgniteCheckedException(org.apache.ignite.IgniteCheckedException)

Example 2 with GridNearTxRemote

use of org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxRemote in project ignite by apache.

the class GridDhtTransactionalCacheAdapter method processDhtLockRequest0.

/**
 * @param nodeId Node ID.
 * @param req Request.
 */
private void processDhtLockRequest0(UUID nodeId, GridDhtLockRequest req) {
    assert nodeId != null;
    assert req != null;
    assert !nodeId.equals(locNodeId);
    int cnt = F.size(req.keys());
    GridDhtLockResponse res;
    GridDhtTxRemote dhtTx = null;
    GridNearTxRemote nearTx = null;
    boolean fail = false;
    boolean cancelled = false;
    try {
        res = new GridDhtLockResponse(ctx.cacheId(), req.version(), req.futureId(), req.miniId(), cnt, ctx.deploymentEnabled());
        dhtTx = startRemoteTx(nodeId, req, res);
        nearTx = isNearEnabled(cacheCfg) ? near().startRemoteTx(nodeId, req) : null;
        if (nearTx != null && !nearTx.empty())
            res.nearEvicted(nearTx.evicted());
        else {
            if (!F.isEmpty(req.nearKeys())) {
                Collection<IgniteTxKey> nearEvicted = new ArrayList<>(req.nearKeys().size());
                nearEvicted.addAll(F.viewReadOnly(req.nearKeys(), new C1<KeyCacheObject, IgniteTxKey>() {

                    @Override
                    public IgniteTxKey apply(KeyCacheObject k) {
                        return ctx.txKey(k);
                    }
                }));
                res.nearEvicted(nearEvicted);
            }
        }
    } catch (IgniteTxRollbackCheckedException e) {
        String err = "Failed processing DHT lock request (transaction has been completed): " + req;
        U.error(log, err, e);
        res = new GridDhtLockResponse(ctx.cacheId(), req.version(), req.futureId(), req.miniId(), new IgniteTxRollbackCheckedException(err, e), ctx.deploymentEnabled());
        fail = true;
    } catch (IgniteCheckedException e) {
        String err = "Failed processing DHT lock request: " + req;
        U.error(log, err, e);
        res = new GridDhtLockResponse(ctx.cacheId(), req.version(), req.futureId(), req.miniId(), new IgniteCheckedException(err, e), ctx.deploymentEnabled());
        fail = true;
    } catch (GridDistributedLockCancelledException ignored) {
        // Received lock request for cancelled lock.
        if (log.isDebugEnabled())
            log.debug("Received lock request for canceled lock (will ignore): " + req);
        res = null;
        fail = true;
        cancelled = true;
    }
    boolean releaseAll = false;
    if (res != null) {
        try {
            // Reply back to sender.
            ctx.io().send(nodeId, res, ctx.ioPolicy());
            if (txLockMsgLog.isDebugEnabled()) {
                txLockMsgLog.debug("Sent dht lock response [txId=" + req.nearXidVersion() + ", dhtTxId=" + req.version() + ", inTx=" + req.inTx() + ", node=" + nodeId + ']');
            }
        } catch (ClusterTopologyCheckedException ignored) {
            U.warn(txLockMsgLog, "Failed to send dht lock response, node failed [" + "txId=" + req.nearXidVersion() + ", dhtTxId=" + req.version() + ", inTx=" + req.inTx() + ", node=" + nodeId + ']');
            fail = true;
            releaseAll = true;
        } catch (IgniteCheckedException e) {
            U.error(txLockMsgLog, "Failed to send dht lock response (lock will not be acquired) " + "txId=" + req.nearXidVersion() + ", dhtTxId=" + req.version() + ", inTx=" + req.inTx() + ", node=" + nodeId + ']', e);
            fail = true;
        }
    }
    if (fail) {
        if (dhtTx != null)
            dhtTx.rollbackRemoteTx();
        if (// Even though this should never happen, we leave this check for consistency.
        nearTx != null)
            nearTx.rollbackRemoteTx();
        List<KeyCacheObject> keys = req.keys();
        if (keys != null) {
            for (KeyCacheObject key : keys) {
                while (true) {
                    GridDistributedCacheEntry entry = peekExx(key);
                    try {
                        if (entry != null) {
                            // Release all locks because sender node left grid.
                            if (releaseAll)
                                entry.removeExplicitNodeLocks(req.nodeId());
                            else
                                entry.removeLock(req.version());
                        }
                        break;
                    } catch (GridCacheEntryRemovedException ignore) {
                        if (log.isDebugEnabled())
                            log.debug("Attempted to remove lock on removed entity during during failure " + "handling for dht lock request (will retry): " + entry);
                    }
                }
            }
        }
        if (releaseAll && !cancelled)
            U.warn(log, "Sender node left grid in the midst of lock acquisition (locks have been released).");
    }
}
Also used : GridDistributedCacheEntry(org.apache.ignite.internal.processors.cache.distributed.GridDistributedCacheEntry) GridDistributedLockCancelledException(org.apache.ignite.internal.processors.cache.distributed.GridDistributedLockCancelledException) ArrayList(java.util.ArrayList) IgniteTxRollbackCheckedException(org.apache.ignite.internal.transactions.IgniteTxRollbackCheckedException) GridNearTxRemote(org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxRemote) C1(org.apache.ignite.internal.util.typedef.C1) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) GridCacheEntryRemovedException(org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException) IgniteTxKey(org.apache.ignite.internal.processors.cache.transactions.IgniteTxKey) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) ClusterTopologyCheckedException(org.apache.ignite.internal.cluster.ClusterTopologyCheckedException)

Example 3 with GridNearTxRemote

use of org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxRemote in project ignite by apache.

the class IgniteTxHandler method processDhtTxFinishRequest.

/**
 * @param nodeId Node ID.
 * @param req Request.
 */
@SuppressWarnings({ "unchecked" })
private void processDhtTxFinishRequest(final UUID nodeId, final GridDhtTxFinishRequest req) {
    try (TraceSurroundings ignored = MTC.support(ctx.kernalContext().tracing().create(TX_PROCESS_DHT_FINISH_REQ, MTC.span()))) {
        assert nodeId != null;
        assert req != null;
        if (req.checkCommitted()) {
            boolean committed = req.waitRemoteTransactions() || !ctx.tm().addRolledbackTx(null, req.version());
            if (!committed || req.syncMode() != FULL_SYNC)
                sendReply(nodeId, req, committed, null);
            else {
                IgniteInternalFuture<?> fut = ctx.tm().remoteTxFinishFuture(req.version());
                fut.listen(new CI1<IgniteInternalFuture<?>>() {

                    @Override
                    public void apply(IgniteInternalFuture<?> fut) {
                        sendReply(nodeId, req, true, null);
                    }
                });
            }
            return;
        }
        // Always add version to rollback history to prevent races with rollbacks.
        if (!req.commit())
            ctx.tm().addRolledbackTx(null, req.version());
        GridDhtTxRemote dhtTx = ctx.tm().tx(req.version());
        GridNearTxRemote nearTx = ctx.tm().nearTx(req.version());
        IgniteInternalTx anyTx = U.<IgniteInternalTx>firstNotNull(dhtTx, nearTx);
        final GridCacheVersion nearTxId = anyTx != null ? anyTx.nearXidVersion() : null;
        if (txFinishMsgLog.isDebugEnabled())
            txFinishMsgLog.debug("Received dht finish request [txId=" + nearTxId + ", dhtTxId=" + req.version() + ", node=" + nodeId + ']');
        if (anyTx == null && req.commit())
            ctx.tm().addCommittedTx(null, req.version(), null);
        if (dhtTx != null)
            finish(nodeId, dhtTx, req);
        else {
            try {
                applyPartitionsUpdatesCounters(req.updateCounters(), !req.commit(), false);
            } catch (IgniteCheckedException e) {
                throw new IgniteException(e);
            }
        }
        if (nearTx != null)
            finish(nodeId, nearTx, req);
        if (req.replyRequired()) {
            IgniteInternalFuture completeFut;
            IgniteInternalFuture<IgniteInternalTx> dhtFin = dhtTx == null ? null : dhtTx.done() ? null : dhtTx.finishFuture();
            final IgniteInternalFuture<IgniteInternalTx> nearFin = nearTx == null ? null : nearTx.done() ? null : nearTx.finishFuture();
            if (dhtFin != null && nearFin != null) {
                GridCompoundFuture fut = new GridCompoundFuture();
                fut.add(dhtFin);
                fut.add(nearFin);
                fut.markInitialized();
                completeFut = fut;
            } else
                completeFut = dhtFin != null ? dhtFin : nearFin;
            if (completeFut != null) {
                completeFut.listen(new CI1<IgniteInternalFuture<IgniteInternalTx>>() {

                    @Override
                    public void apply(IgniteInternalFuture<IgniteInternalTx> fut) {
                        sendReply(nodeId, req, true, nearTxId);
                    }
                });
            } else
                sendReply(nodeId, req, true, nearTxId);
        } else
            sendReply(nodeId, req, true, null);
        assert req.txState() != null || (dhtTx == null && nearTx == null) : req + " tx=" + dhtTx + " nearTx=" + nearTx;
    }
}
Also used : GridDhtTxRemote(org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTxRemote) IgniteInternalFuture(org.apache.ignite.internal.IgniteInternalFuture) TraceSurroundings(org.apache.ignite.internal.processors.tracing.MTC.TraceSurroundings) GridNearTxRemote(org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxRemote) GridCompoundFuture(org.apache.ignite.internal.util.future.GridCompoundFuture) GridCacheVersion(org.apache.ignite.internal.processors.cache.version.GridCacheVersion) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) IgniteException(org.apache.ignite.IgniteException)

Example 4 with GridNearTxRemote

use of org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxRemote in project ignite by apache.

the class IgniteTxHandler method startNearRemoteTx.

/**
 * Called while processing dht tx prepare request.
 *
 * @param ldr Loader.
 * @param nodeId Sender node ID.
 * @param req Request.
 * @return Remote transaction.
 * @throws IgniteCheckedException If failed.
 */
@Nullable
private GridNearTxRemote startNearRemoteTx(ClassLoader ldr, UUID nodeId, GridDhtTxPrepareRequest req) throws IgniteCheckedException {
    if (!F.isEmpty(req.nearWrites())) {
        GridNearTxRemote tx = ctx.tm().nearTx(req.version());
        if (tx == null) {
            tx = new GridNearTxRemote(ctx, req.topologyVersion(), ldr, nodeId, req.nearNodeId(), req.version(), null, req.system(), req.policy(), req.concurrency(), req.isolation(), req.isInvalidate(), req.timeout(), req.nearWrites(), req.txSize(), securitySubjectId(ctx), req.taskNameHash(), req.txLabel());
            tx.writeVersion(req.writeVersion());
            if (!tx.empty()) {
                tx = ctx.tm().onCreated(null, tx);
                if (tx == null || !ctx.tm().onStarted(tx))
                    throw new IgniteTxRollbackCheckedException("Attempt to start a completed transaction: " + tx);
            }
        } else
            tx.addEntries(ldr, req.nearWrites());
        tx.ownedVersions(req.owned());
        // Prepare prior to reordering, so the pending locks added
        // in prepare phase will get properly ordered as well.
        tx.prepareRemoteTx();
        if (req.last())
            tx.state(PREPARED);
        return tx;
    }
    return null;
}
Also used : IgniteTxRollbackCheckedException(org.apache.ignite.internal.transactions.IgniteTxRollbackCheckedException) GridNearTxRemote(org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxRemote) Nullable(org.jetbrains.annotations.Nullable)

Aggregations

GridNearTxRemote (org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxRemote)4 IgniteCheckedException (org.apache.ignite.IgniteCheckedException)3 IgniteTxRollbackCheckedException (org.apache.ignite.internal.transactions.IgniteTxRollbackCheckedException)3 IgniteInternalFuture (org.apache.ignite.internal.IgniteInternalFuture)2 GridDhtTxRemote (org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTxRemote)2 TraceSurroundings (org.apache.ignite.internal.processors.tracing.MTC.TraceSurroundings)2 GridCompoundFuture (org.apache.ignite.internal.util.future.GridCompoundFuture)2 ArrayList (java.util.ArrayList)1 IgniteException (org.apache.ignite.IgniteException)1 ClusterTopologyCheckedException (org.apache.ignite.internal.cluster.ClusterTopologyCheckedException)1 GridCacheEntryRemovedException (org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException)1 KeyCacheObject (org.apache.ignite.internal.processors.cache.KeyCacheObject)1 GridDistributedCacheEntry (org.apache.ignite.internal.processors.cache.distributed.GridDistributedCacheEntry)1 GridDistributedLockCancelledException (org.apache.ignite.internal.processors.cache.distributed.GridDistributedLockCancelledException)1 GridDhtTxPrepareResponse (org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTxPrepareResponse)1 IgniteTxKey (org.apache.ignite.internal.processors.cache.transactions.IgniteTxKey)1 GridCacheVersion (org.apache.ignite.internal.processors.cache.version.GridCacheVersion)1 IgniteTxOptimisticCheckedException (org.apache.ignite.internal.transactions.IgniteTxOptimisticCheckedException)1 C1 (org.apache.ignite.internal.util.typedef.C1)1 Nullable (org.jetbrains.annotations.Nullable)1