Search in sources :

Example 1 with GridDhtTxRemote

use of org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTxRemote 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) {
    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());
        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 if (e instanceof IgniteTxHeuristicCheckedException) {
            U.warn(log, "Failed to commit transaction (all transaction entries were invalidated): " + CU.txString(dhtTx));
        } else
            U.error(log, "Failed to process prepare request: " + req, e);
        if (nearTx != null)
            nearTx.rollbackRemoteTx();
        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 || (ctx.tm().tx(req.version()) == null && ctx.tm().nearTx(req.version()) == null);
}
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) IgniteTxHeuristicCheckedException(org.apache.ignite.internal.transactions.IgniteTxHeuristicCheckedException) 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 GridDhtTxRemote

use of org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTxRemote in project ignite by apache.

the class IgniteTxHandler method startRemoteTx.

/**
     * @param nodeId Node ID.
     * @param req Request.
     * @param res Response.
     * @return Remote transaction.
     * @throws IgniteCheckedException If failed.
     */
@Nullable
GridDhtTxRemote startRemoteTx(UUID nodeId, GridDhtTxPrepareRequest req, GridDhtTxPrepareResponse res) throws IgniteCheckedException {
    if (!F.isEmpty(req.writes())) {
        GridDhtTxRemote tx = ctx.tm().tx(req.version());
        if (tx == null) {
            boolean single = req.last() && req.writes().size() == 1;
            tx = new GridDhtTxRemote(ctx, req.nearNodeId(), req.futureId(), nodeId, req.topologyVersion(), req.version(), null, req.system(), req.policy(), req.concurrency(), req.isolation(), req.isInvalidate(), req.timeout(), req.writes() != null ? Math.max(req.writes().size(), req.txSize()) : req.txSize(), req.nearXidVersion(), req.transactionNodes(), req.subjectId(), req.taskNameHash(), single);
            tx.writeVersion(req.writeVersion());
            tx = ctx.tm().onCreated(null, tx);
            if (tx == null || !ctx.tm().onStarted(tx)) {
                if (log.isDebugEnabled())
                    log.debug("Attempt to start a completed transaction (will ignore): " + tx);
                return null;
            }
            if (ctx.discovery().node(nodeId) == null) {
                tx.state(ROLLING_BACK);
                tx.state(ROLLED_BACK);
                ctx.tm().uncommitTx(tx);
                return null;
            }
        } else {
            tx.writeVersion(req.writeVersion());
            tx.transactionNodes(req.transactionNodes());
        }
        if (!tx.isSystemInvalidate()) {
            int idx = 0;
            for (IgniteTxEntry entry : req.writes()) {
                GridCacheContext cacheCtx = entry.context();
                int part = cacheCtx.affinity().partition(entry.key());
                GridDhtLocalPartition locPart = cacheCtx.topology().localPartition(part, req.topologyVersion(), false);
                if (locPart != null && locPart.reserve()) {
                    try {
                        tx.addWrite(entry, ctx.deploy().globalLoader());
                        if (isNearEnabled(cacheCtx) && req.invalidateNearEntry(idx))
                            invalidateNearEntry(cacheCtx, entry.key(), req.version());
                        if (req.needPreloadKey(idx)) {
                            GridCacheEntryEx cached = entry.cached();
                            if (cached == null)
                                cached = cacheCtx.cache().entryEx(entry.key(), req.topologyVersion());
                            GridCacheEntryInfo info = cached.info();
                            if (info != null && !info.isNew() && !info.isDeleted())
                                res.addPreloadEntry(info);
                        }
                        if (cacheCtx.readThroughConfigured() && !entry.skipStore() && entry.op() == TRANSFORM && entry.oldValueOnPrimary() && !entry.hasValue()) {
                            while (true) {
                                try {
                                    GridCacheEntryEx cached = entry.cached();
                                    if (cached == null) {
                                        cached = cacheCtx.cache().entryEx(entry.key(), req.topologyVersion());
                                        entry.cached(cached);
                                    }
                                    CacheObject val = cached.innerGet(/*ver*/
                                    null, tx, /*readThrough*/
                                    false, /*updateMetrics*/
                                    false, /*evt*/
                                    false, tx.subjectId(), /*transformClo*/
                                    null, tx.resolveTaskName(), /*expiryPlc*/
                                    null, /*keepBinary*/
                                    true);
                                    if (val == null)
                                        val = cacheCtx.toCacheObject(cacheCtx.store().load(null, entry.key()));
                                    if (val != null)
                                        entry.readValue(val);
                                    break;
                                } catch (GridCacheEntryRemovedException ignored) {
                                    if (log.isDebugEnabled())
                                        log.debug("Got entry removed exception, will retry: " + entry.txKey());
                                    entry.cached(cacheCtx.cache().entryEx(entry.key(), req.topologyVersion()));
                                }
                            }
                        }
                    } catch (GridDhtInvalidPartitionException e) {
                        tx.addInvalidPartition(cacheCtx, e.partition());
                        tx.clearEntry(entry.txKey());
                    } finally {
                        locPart.release();
                    }
                } else
                    tx.addInvalidPartition(cacheCtx, part);
                idx++;
            }
        }
        // Prepare prior to reordering, so the pending locks added
        // in prepare phase will get properly ordered as well.
        tx.prepareRemoteTx();
        if (req.last()) {
            assert !F.isEmpty(req.transactionNodes()) : "Received last prepare request with empty transaction nodes: " + req;
            tx.state(PREPARED);
        }
        res.invalidPartitionsByCacheId(tx.invalidPartitions());
        if (tx.empty() && req.last()) {
            tx.rollbackRemoteTx();
            return null;
        }
        return tx;
    }
    return null;
}
Also used : GridCacheEntryInfo(org.apache.ignite.internal.processors.cache.GridCacheEntryInfo) GridDhtInvalidPartitionException(org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtInvalidPartitionException) GridDhtTxRemote(org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTxRemote) GridCacheEntryEx(org.apache.ignite.internal.processors.cache.GridCacheEntryEx) GridCacheContext(org.apache.ignite.internal.processors.cache.GridCacheContext) GridCacheEntryRemovedException(org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException) GridDhtLocalPartition(org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtLocalPartition) CacheObject(org.apache.ignite.internal.processors.cache.CacheObject) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) Nullable(org.jetbrains.annotations.Nullable)

Example 3 with GridDhtTxRemote

use of org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTxRemote 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) {
    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;
    }
    final GridDhtTxRemote dhtTx = ctx.tm().tx(req.version());
    GridNearTxRemote nearTx = ctx.tm().nearTx(req.version());
    final GridCacheVersion nearTxId = (dhtTx != null ? dhtTx.nearXidVersion() : (nearTx != null ? nearTx.nearXidVersion() : null));
    if (txFinishMsgLog.isDebugEnabled()) {
        txFinishMsgLog.debug("Received dht finish request [txId=" + nearTxId + ", dhtTxId=" + req.version() + ", node=" + nodeId + ']');
    }
    // Safety - local transaction will finish explicitly.
    if (nearTx != null && nearTx.local())
        nearTx = null;
    finish(nodeId, dhtTx, req);
    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);
    IgniteInternalTx tx0 = ctx.tm().tx(req.version());
    IgniteInternalTx nearTx0 = ctx.tm().nearTx(req.version());
    assert req.txState() != null || (tx0 == null && nearTx0 == null) : req + " tx=" + tx0 + " nearTx=" + nearTx0;
}
Also used : GridDhtTxRemote(org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTxRemote) GridCacheVersion(org.apache.ignite.internal.processors.cache.version.GridCacheVersion) IgniteInternalFuture(org.apache.ignite.internal.IgniteInternalFuture) GridNearTxRemote(org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxRemote) GridCompoundFuture(org.apache.ignite.internal.util.future.GridCompoundFuture)

Example 4 with GridDhtTxRemote

use of org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTxRemote in project ignite by apache.

the class IgniteTxManager method commitIfPrepared.

/**
     * Commits transaction in case when node started transaction failed, but all related
     * transactions were prepared (invalidates transaction if it is not fully prepared).
     *
     * @param tx Transaction.
     * @param failedNodeIds Failed nodes IDs.
     */
public void commitIfPrepared(IgniteInternalTx tx, Set<UUID> failedNodeIds) {
    assert tx instanceof GridDhtTxLocal || tx instanceof GridDhtTxRemote : tx;
    assert !F.isEmpty(tx.transactionNodes()) : tx;
    assert tx.nearXidVersion() != null : tx;
    GridCacheTxRecoveryFuture fut = new GridCacheTxRecoveryFuture(cctx, tx, failedNodeIds, tx.transactionNodes());
    cctx.mvcc().addFuture(fut, fut.futureId());
    if (log.isDebugEnabled())
        log.debug("Checking optimistic transaction state on remote nodes [tx=" + tx + ", fut=" + fut + ']');
    fut.prepare();
}
Also used : GridDhtTxRemote(org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTxRemote) GridDhtTxLocal(org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTxLocal) GridCacheTxRecoveryFuture(org.apache.ignite.internal.processors.cache.distributed.GridCacheTxRecoveryFuture)

Aggregations

GridDhtTxRemote (org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTxRemote)4 IgniteInternalFuture (org.apache.ignite.internal.IgniteInternalFuture)2 GridNearTxRemote (org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxRemote)2 GridCompoundFuture (org.apache.ignite.internal.util.future.GridCompoundFuture)2 IgniteCheckedException (org.apache.ignite.IgniteCheckedException)1 CacheObject (org.apache.ignite.internal.processors.cache.CacheObject)1 GridCacheContext (org.apache.ignite.internal.processors.cache.GridCacheContext)1 GridCacheEntryEx (org.apache.ignite.internal.processors.cache.GridCacheEntryEx)1 GridCacheEntryInfo (org.apache.ignite.internal.processors.cache.GridCacheEntryInfo)1 GridCacheEntryRemovedException (org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException)1 KeyCacheObject (org.apache.ignite.internal.processors.cache.KeyCacheObject)1 GridCacheTxRecoveryFuture (org.apache.ignite.internal.processors.cache.distributed.GridCacheTxRecoveryFuture)1 GridDhtInvalidPartitionException (org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtInvalidPartitionException)1 GridDhtLocalPartition (org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtLocalPartition)1 GridDhtTxLocal (org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTxLocal)1 GridDhtTxPrepareResponse (org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTxPrepareResponse)1 GridCacheVersion (org.apache.ignite.internal.processors.cache.version.GridCacheVersion)1 IgniteTxHeuristicCheckedException (org.apache.ignite.internal.transactions.IgniteTxHeuristicCheckedException)1 IgniteTxOptimisticCheckedException (org.apache.ignite.internal.transactions.IgniteTxOptimisticCheckedException)1 IgniteTxRollbackCheckedException (org.apache.ignite.internal.transactions.IgniteTxRollbackCheckedException)1