Search in sources :

Example 1 with DR_PRIMARY

use of org.apache.ignite.internal.processors.dr.GridDrType.DR_PRIMARY in project ignite by apache.

the class IgniteTxLocalAdapter method userCommit.

/**
 * {@inheritDoc}
 */
@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) && !queryEnlisted();
    // locks on backup nodes.
    if (!empty || colocated())
        cctx.tm().addCommittedTx(this);
    if (!empty) {
        batchStoreCommit(writeEntries());
        WALPointer ptr = null;
        IgniteCheckedException err = null;
        cctx.database().checkpointReadLock();
        try {
            cctx.tm().txContext(this);
            AffinityTopologyVersion topVer = topologyVersion();
            TxCounters txCounters = txCounters(false);
            /*
                 * 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();
                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;
                            boolean updateNearCache = updateNearCache(cacheCtx, txEntry.key(), topVer);
                            boolean metrics = true;
                            if (!updateNearCache && 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, resolveTaskName(), dhtVer, null);
                                if (updRes.success())
                                    txEntry.updateCounter(updRes.updateCounter());
                                if (updRes.loggedPointer() != null)
                                    ptr = updRes.loggedPointer();
                                if (updRes.success() && updateNearCache) {
                                    final CacheObject val0 = val;
                                    final boolean metrics0 = metrics;
                                    final GridCacheVersion dhtVer0 = dhtVer;
                                    updateNearEntrySafely(cacheCtx, txEntry.key(), entry -> entry.innerSet(null, eventNodeId(), nodeId, val0, false, false, txEntry.ttl(), false, metrics0, txEntry.keepBinary(), txEntry.hasOldValue(), txEntry.oldValue(), topVer, CU.empty0(), DR_NONE, txEntry.conflictExpireTime(), null, resolveTaskName(), dhtVer0, 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, resolveTaskName(), dhtVer, null);
                                if (updRes.success())
                                    txEntry.updateCounter(updRes.updateCounter());
                                if (updRes.loggedPointer() != null)
                                    ptr = updRes.loggedPointer();
                                if (updRes.success() && updateNearCache) {
                                    final boolean metrics0 = metrics;
                                    final GridCacheVersion dhtVer0 = dhtVer;
                                    updateNearEntrySafely(cacheCtx, txEntry.key(), entry -> entry.innerRemove(null, eventNodeId(), nodeId, false, false, metrics0, txEntry.keepBinary(), txEntry.hasOldValue(), txEntry.oldValue(), topVer, CU.empty0(), DR_NONE, null, resolveTaskName(), dhtVer0, null));
                                }
                            } else if (op == RELOAD) {
                                cached.innerReload();
                                if (updateNearCache)
                                    updateNearEntrySafely(cacheCtx, txEntry.key(), entry -> entry.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(), DataEntry.flags(CU.txOnPrimary(this)))));
                                }
                                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()));
                    }
                }
            }
            if (!txState.mvccEnabled() && txCounters != null) {
                cctx.tm().txHandler().applyPartitionsUpdatesCounters(txCounters.updateCounters());
                for (IgniteTxEntry entry : commitEntries) {
                    if (entry.cqNotifyClosure() != null)
                        entry.cqNotifyClosure().applyx();
                }
            }
            // Apply cache sizes only for primary nodes. Update counters were applied on prepare state.
            applyTxSizes();
            cctx.mvccCaching().onTxFinished(this, true);
            if (ptr != null)
                cctx.wal().flush(ptr, false);
        } 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, NodeStoppingException.class)) {
                U.warn(log, "Failed to commit transaction, node is stopping [tx=" + CU.txString(this) + ", err=" + ex + ']');
                boolean persistenceEnabled = CU.isPersistenceEnabled(cctx.kernalContext().config());
                if (persistenceEnabled) {
                    GridCacheDatabaseSharedManager dbManager = (GridCacheDatabaseSharedManager) cctx.database();
                    dbManager.getCheckpointer().skipCheckpointOnNodeStop(true);
                }
                throw ex;
            }
            err = heuristicException(ex);
            COMMIT_ERR_UPD.compareAndSet(this, null, err);
            state(UNKNOWN);
            try {
                uncommit();
            } catch (Throwable e) {
                err.addSuppressed(e);
            }
            throw err;
        } 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 : IgniteInternalFuture(org.apache.ignite.internal.IgniteInternalFuture) GridCacheFilterFailedException(org.apache.ignite.internal.processors.cache.GridCacheFilterFailedException) GridCacheMvccCandidate(org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate) IgniteTxRollbackCheckedException(org.apache.ignite.internal.transactions.IgniteTxRollbackCheckedException) GridFinishedFuture(org.apache.ignite.internal.util.future.GridFinishedFuture) TRANSFORM(org.apache.ignite.internal.processors.cache.GridCacheOperation.TRANSFORM) GridCacheVersionConflictContext(org.apache.ignite.internal.processors.cache.version.GridCacheVersionConflictContext) WALPointer(org.apache.ignite.internal.processors.cache.persistence.wal.WALPointer) EntryProcessor(javax.cache.processor.EntryProcessor) UNKNOWN(org.apache.ignite.transactions.TransactionState.UNKNOWN) CREATE(org.apache.ignite.internal.processors.cache.GridCacheOperation.CREATE) Map(java.util.Map) X(org.apache.ignite.internal.util.typedef.X) IgniteCacheExpiryPolicy(org.apache.ignite.internal.processors.cache.IgniteCacheExpiryPolicy) DELETE(org.apache.ignite.internal.processors.cache.GridCacheOperation.DELETE) GridCacheUpdateTxResult(org.apache.ignite.internal.processors.cache.GridCacheUpdateTxResult) PartitionUpdateCountersMessage(org.apache.ignite.internal.processors.cache.distributed.dht.PartitionUpdateCountersMessage) RELOAD(org.apache.ignite.internal.processors.cache.GridCacheOperation.RELOAD) AtomicReferenceFieldUpdater(java.util.concurrent.atomic.AtomicReferenceFieldUpdater) IgniteTxTimeoutCheckedException(org.apache.ignite.internal.transactions.IgniteTxTimeoutCheckedException) Collection(java.util.Collection) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) TransactionConcurrency(org.apache.ignite.transactions.TransactionConcurrency) TransactionDeadlockException(org.apache.ignite.transactions.TransactionDeadlockException) Set(java.util.Set) OWNING(org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtPartitionState.OWNING) UUID(java.util.UUID) CacheObject(org.apache.ignite.internal.processors.cache.CacheObject) DataRecord(org.apache.ignite.internal.pagemem.wal.record.DataRecord) GridCacheEntryRemovedException(org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException) DataEntry(org.apache.ignite.internal.pagemem.wal.record.DataEntry) GridCacheOperation(org.apache.ignite.internal.processors.cache.GridCacheOperation) IgniteBiTuple(org.apache.ignite.lang.IgniteBiTuple) Nullable(org.jetbrains.annotations.Nullable) List(java.util.List) NOOP(org.apache.ignite.internal.processors.cache.GridCacheOperation.NOOP) GridDhtPartitionTopology(org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtPartitionTopology) CU(org.apache.ignite.internal.util.typedef.internal.CU) LOST(org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtPartitionState.LOST) GridCacheContext(org.apache.ignite.internal.processors.cache.GridCacheContext) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) ROLLING_BACK(org.apache.ignite.transactions.TransactionState.ROLLING_BACK) GridCacheEntryEx(org.apache.ignite.internal.processors.cache.GridCacheEntryEx) TransactionIsolation(org.apache.ignite.transactions.TransactionIsolation) NodeStoppingException(org.apache.ignite.internal.NodeStoppingException) DR_NONE(org.apache.ignite.internal.processors.dr.GridDrType.DR_NONE) AtomicIntegerFieldUpdater(java.util.concurrent.atomic.AtomicIntegerFieldUpdater) IgniteThread(org.apache.ignite.thread.IgniteThread) GridCacheReturn(org.apache.ignite.internal.processors.cache.GridCacheReturn) GridCacheVersion(org.apache.ignite.internal.processors.cache.version.GridCacheVersion) U(org.apache.ignite.internal.util.typedef.internal.U) IgniteBiClosure(org.apache.ignite.lang.IgniteBiClosure) CacheGroupContext(org.apache.ignite.internal.processors.cache.CacheGroupContext) ArrayList(java.util.ArrayList) COMMITTING(org.apache.ignite.transactions.TransactionState.COMMITTING) GridCacheDatabaseSharedManager(org.apache.ignite.internal.processors.cache.persistence.GridCacheDatabaseSharedManager) GridTuple(org.apache.ignite.internal.util.lang.GridTuple) CacheWriteSynchronizationMode(org.apache.ignite.cache.CacheWriteSynchronizationMode) GridDrType(org.apache.ignite.internal.processors.dr.GridDrType) DR_PRIMARY(org.apache.ignite.internal.processors.dr.GridDrType.DR_PRIMARY) Duration(javax.cache.expiry.Duration) CacheStoreManager(org.apache.ignite.internal.processors.cache.store.CacheStoreManager) C1(org.apache.ignite.internal.util.typedef.C1) F(org.apache.ignite.internal.util.typedef.F) ExpiryPolicy(javax.cache.expiry.ExpiryPolicy) GridNearTxLocal(org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxLocal) IgniteTxHeuristicCheckedException(org.apache.ignite.internal.transactions.IgniteTxHeuristicCheckedException) AffinityTopologyVersion(org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion) ROLLED_BACK(org.apache.ignite.transactions.TransactionState.ROLLED_BACK) UPDATE(org.apache.ignite.internal.processors.cache.GridCacheOperation.UPDATE) COMMITTED(org.apache.ignite.transactions.TransactionState.COMMITTED) PREPARING(org.apache.ignite.transactions.TransactionState.PREPARING) GridToStringInclude(org.apache.ignite.internal.util.tostring.GridToStringInclude) T2(org.apache.ignite.internal.util.typedef.T2) MARKED_ROLLBACK(org.apache.ignite.transactions.TransactionState.MARKED_ROLLBACK) AtomicLong(java.util.concurrent.atomic.AtomicLong) GridDhtLocalPartition(org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtLocalPartition) GridCacheSharedContext(org.apache.ignite.internal.processors.cache.GridCacheSharedContext) TransactionState(org.apache.ignite.transactions.TransactionState) CacheEntryPredicate(org.apache.ignite.internal.processors.cache.CacheEntryPredicate) EntryProcessorResourceInjectorProxy(org.apache.ignite.internal.processors.cache.EntryProcessorResourceInjectorProxy) CacheInvokeEntry(org.apache.ignite.internal.processors.cache.CacheInvokeEntry) GridToStringBuilder(org.apache.ignite.internal.util.tostring.GridToStringBuilder) CX1(org.apache.ignite.internal.util.typedef.CX1) Collections(java.util.Collections) GridClosureException(org.apache.ignite.internal.util.lang.GridClosureException) READ(org.apache.ignite.internal.processors.cache.GridCacheOperation.READ) TransactionState(org.apache.ignite.transactions.TransactionState) NodeStoppingException(org.apache.ignite.internal.NodeStoppingException) 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.processors.cache.persistence.wal.WALPointer) GridCacheContext(org.apache.ignite.internal.processors.cache.GridCacheContext) AffinityTopologyVersion(org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion) GridCacheDatabaseSharedManager(org.apache.ignite.internal.processors.cache.persistence.GridCacheDatabaseSharedManager) 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)

Aggregations

ArrayList (java.util.ArrayList)1 Collection (java.util.Collection)1 Collections (java.util.Collections)1 List (java.util.List)1 Map (java.util.Map)1 Set (java.util.Set)1 UUID (java.util.UUID)1 AtomicIntegerFieldUpdater (java.util.concurrent.atomic.AtomicIntegerFieldUpdater)1 AtomicLong (java.util.concurrent.atomic.AtomicLong)1 AtomicReferenceFieldUpdater (java.util.concurrent.atomic.AtomicReferenceFieldUpdater)1 Duration (javax.cache.expiry.Duration)1 ExpiryPolicy (javax.cache.expiry.ExpiryPolicy)1 EntryProcessor (javax.cache.processor.EntryProcessor)1 IgniteCheckedException (org.apache.ignite.IgniteCheckedException)1 CacheWriteSynchronizationMode (org.apache.ignite.cache.CacheWriteSynchronizationMode)1 IgniteInternalFuture (org.apache.ignite.internal.IgniteInternalFuture)1 NodeStoppingException (org.apache.ignite.internal.NodeStoppingException)1 DataEntry (org.apache.ignite.internal.pagemem.wal.record.DataEntry)1 DataRecord (org.apache.ignite.internal.pagemem.wal.record.DataRecord)1 AffinityTopologyVersion (org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion)1