Search in sources :

Example 1 with GridNearTxFinishResponse

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

the class IgniteTxHandler method finishDhtLocal.

/**
 * @param nodeId Node ID initiated commit.
 * @param locTx Optional local transaction.
 * @param req Finish request.
 * @return Finish future.
 */
private IgniteInternalFuture<IgniteInternalTx> finishDhtLocal(UUID nodeId, @Nullable GridNearTxLocal locTx, GridNearTxFinishRequest req) {
    GridCacheVersion dhtVer = ctx.tm().mappedVersion(req.version());
    GridDhtTxLocal tx = null;
    if (dhtVer == null) {
        if (log.isDebugEnabled())
            log.debug("Received transaction finish request for unknown near version (was lock explicit?): " + req);
    } else
        tx = ctx.tm().tx(dhtVer);
    if (tx != null)
        req.txState(tx.txState());
    if (tx == null && locTx != null && !req.commit()) {
        U.warn(log, "DHT local tx not found for near local tx rollback " + "[req=" + req + ", dhtVer=" + dhtVer + ", tx=" + locTx + ']');
        return null;
    }
    if (tx == null && !req.explicitLock()) {
        assert locTx == null : "DHT local tx should never be lost for near local tx: " + locTx;
        U.warn(txFinishMsgLog, "Received finish request for completed transaction (the message may be too late) [" + "txId=" + req.version() + ", dhtTxId=" + dhtVer + ", node=" + nodeId + ", commit=" + req.commit() + ']');
        // Always send finish response.
        GridCacheMessage res = new GridNearTxFinishResponse(req.partition(), req.version(), req.threadId(), req.futureId(), req.miniId(), new IgniteCheckedException("Transaction has been already completed."));
        try {
            ctx.io().send(nodeId, res, req.policy());
            if (txFinishMsgLog.isDebugEnabled()) {
                txFinishMsgLog.debug("Sent near finish response for completed tx [txId=" + req.version() + ", dhtTxId=" + dhtVer + ", node=" + nodeId + ']');
            }
        } catch (Throwable e) {
            // Double-check.
            if (ctx.discovery().node(nodeId) == null) {
                if (txFinishMsgLog.isDebugEnabled()) {
                    txFinishMsgLog.debug("Failed to send near finish response for completed tx, node failed [" + "txId=" + req.version() + ", dhtTxId=" + dhtVer + ", node=" + nodeId + ']');
                }
            } else {
                U.error(txFinishMsgLog, "Failed to send near finish response for completed tx, node failed [" + "txId=" + req.version() + ", dhtTxId=" + dhtVer + ", node=" + nodeId + ", req=" + req + ", res=" + res + ']', e);
            }
            if (e instanceof Error)
                throw (Error) e;
        }
        return null;
    }
    try {
        assert tx != null : "Transaction is null for near finish request [nodeId=" + nodeId + ", req=" + req + "]";
        assert req.syncMode() != null : req;
        tx.syncMode(req.syncMode());
        tx.nearFinishFutureId(req.futureId());
        tx.nearFinishMiniId(req.miniId());
        tx.storeEnabled(req.storeEnabled());
        if (req.commit()) {
            if (!tx.markFinalizing(USER_FINISH)) {
                if (log.isDebugEnabled())
                    log.debug("Will not finish transaction (it is handled by another thread): " + tx);
                return null;
            }
            IgniteInternalFuture<IgniteInternalTx> commitFut = tx.commitDhtLocalAsync();
            // Only for error logging.
            commitFut.listen(CU.errorLogger(log));
            return commitFut;
        } else {
            IgniteInternalFuture<IgniteInternalTx> rollbackFut = tx.rollbackDhtLocalAsync();
            // Only for error logging.
            rollbackFut.listen(CU.errorLogger(log));
            return rollbackFut;
        }
    } catch (Throwable e) {
        U.error(log, "Failed completing transaction [commit=" + req.commit() + ", tx=" + tx + ']', e);
        if (tx != null) {
            tx.commitError(e);
            tx.systemInvalidate(true);
            try {
                IgniteInternalFuture<IgniteInternalTx> res = tx.rollbackDhtLocalAsync();
                // Only for error logging.
                res.listen(CU.errorLogger(log));
                return res;
            } catch (Throwable e1) {
                e.addSuppressed(e1);
            }
        }
        if (e instanceof Error)
            throw (Error) e;
        return new GridFinishedFuture<>(e);
    }
}
Also used : GridCacheVersion(org.apache.ignite.internal.processors.cache.version.GridCacheVersion) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) GridDhtTxLocal(org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTxLocal) IgniteInternalFuture(org.apache.ignite.internal.IgniteInternalFuture) GridCacheMessage(org.apache.ignite.internal.processors.cache.GridCacheMessage) GridNearTxFinishResponse(org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxFinishResponse)

Aggregations

IgniteCheckedException (org.apache.ignite.IgniteCheckedException)1 IgniteInternalFuture (org.apache.ignite.internal.IgniteInternalFuture)1 GridCacheMessage (org.apache.ignite.internal.processors.cache.GridCacheMessage)1 GridDhtTxLocal (org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTxLocal)1 GridNearTxFinishResponse (org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxFinishResponse)1 GridCacheVersion (org.apache.ignite.internal.processors.cache.version.GridCacheVersion)1