/** * * @param tx Transaction to check. * @return {@code True} if transaction has been committed or rolled back, * {@code false} otherwise. */ private boolean isCompleted(IgniteInternalTx tx) { boolean completed = completedVersHashMap.containsKey(tx.xidVersion()); // Need check that for tx rollback message was not received before lock. // This could happen on timeout or async rollback. if (!completed && tx.local() && tx.dht()) return completedVersHashMap.containsKey(tx.nearXidVersion()); return completed; }
/** * @param tx Transaction to notify evictions for. */ private void notifyEvictions(IgniteInternalTx tx) { if (tx.internal()) return; for (IgniteTxEntry txEntry : tx.allEntries()) txEntry.cached().context().evicts().touch(txEntry, tx.local()); }
/** * Initializes this future. */ public void init() { if (remainingTxs == null) { remainingTxs = Collections.emptySet(); onDone(true); } else { assert !remainingTxs.isEmpty(); for (final IgniteInternalTx tx : remainingTxs) { if (!tx.done()) { tx.finishFuture().listen(new CI1<IgniteInternalFuture<IgniteInternalTx>>() { @Override public void apply(IgniteInternalFuture<IgniteInternalTx> t) { remainingTxs.remove(tx); checkRemaining(); } }); } else remainingTxs.remove(tx); } checkRemaining(); } }
/** * @param tx Transaction. * @return {@code True} if given transaction is explicitly started user transaction. */ private boolean activeUserTx(@Nullable IgniteInternalTx tx) { if (tx != null && tx.user() && tx.state() == ACTIVE) { assert tx instanceof GridNearTxLocal : tx; return true; } return false; }
assert tx.state() == COMMITTING : "Invalid transaction state for commit from tm [state=" + tx.state() + ", expected=COMMITTING, tx=" + tx + ']'; Object committed0 = completedVersHashMap.get(tx.xidVersion()); if (!(committed || tx.writeSet().isEmpty() || tx.isSystemInvalidate())) { uncommitTx(tx); tx.errorWhenCommitting(); IGNITE_MAX_COMPLETED_TX_COUNT + " system property) [ver=" + tx.xidVersion() + ", committed0=" + committed0 + ", tx=" + tx.getClass().getSimpleName() + ']'); if (txIdMap.remove(tx.xidVersion(), tx)) { unlockMultiple(tx, tx.writeEntries()); unlockMultiple(tx, tx.readEntries()); tx.endVersion(cctx.versions().next(tx.topologyVersion())); if (!tx.alternateVersions().isEmpty()) { for (GridCacheVersion ver : tx.alternateVersions()) idMap.remove(ver); if (!tx.dht() && tx.local()) { if (!tx.system()) cctx.txMetrics().onTxCommit();
if ((tx.near() && !tx.local()) || (tx.storeWriteThrough() && tx.masterNodeIds().contains(evtNodeId))) { if (tx.originatingNodeId().equals(evtNodeId)) { if (tx.state() == PREPARED) commitIfPrepared(tx, Collections.singleton(evtNodeId)); else { IgniteInternalFuture<?> prepFut = tx.currentPrepareFuture(); if (tx.state() == PREPARED) commitIfPrepared(tx, Collections.singleton(evtNodeId)); else if (tx.setRollbackOnly()) tx.rollbackAsync(); }); else if (tx.setRollbackOnly()) tx.rollbackAsync(); if (allTxFinFut != null && tx.eventNodeId().equals(evtNodeId) && tx.mvccSnapshot() != null) allTxFinFut.add(tx.finishFuture());
/** * @param tx Transaction. * @return String view of all safe-to-print transaction properties. */ public static String txString(@Nullable IgniteInternalTx tx) { if (tx == null) return "null"; return tx.getClass().getSimpleName() + "[xid=" + tx.xid() + ", xidVersion=" + tx.xidVersion() + ", concurrency=" + tx.concurrency() + ", isolation=" + tx.isolation() + ", state=" + tx.state() + ", invalidate=" + tx.isInvalidate() + ", rollbackOnly=" + tx.isRollbackOnly() + ", nodeId=" + tx.nodeId() + ", timeout=" + tx.timeout() + ", duration=" + (U.currentTimeMillis() - tx.startTime()) + (tx instanceof GridNearTxLocal ? ", label=" + ((GridNearTxLocal)tx).label() : "") + ']'; }
assert tx.optimistic() || !tx.local(); long remainingTime = tx.remainingTime(); GridCacheVersion serOrder = (tx.serializable() && tx.optimistic()) ? tx.nearXidVersion() : null; assert serReadVer == null || (tx.optimistic() && tx.serializable()) : txEntry1; txEntry1.cached(cacheCtx.cache().entryEx(txEntry1.key(), tx.topologyVersion())); assert tx.dht() : "Received invalid partition for non DHT transaction [tx=" + tx + ", invalidPart=" + e.partition() + ']'; tx.addInvalidPartition(cacheCtx, e.partition()); tx.setRollbackOnly();
final boolean valid = valid(tx != null ? tx.topologyVersion() : topVer); assert tx == null || (!tx.local() && tx.onePhaseCommit()) || tx.ownsLock(this) : "Transaction does not own lock for remove[entry=" + this + ", tx=" + tx + ']'; newVer = explicitVer != null ? explicitVer : tx == null ? nextVersion() : tx.writeVersion(); GridCacheMvcc mvcc = mvccExtras(); if (mvcc == null || mvcc.isEmpty(tx.xidVersion())) clearReaders(); else clearReader(tx.originatingNodeId()); updateCntr0 = nextPartitionCounter(topVer, tx == null || tx.local(), updateCntr); T2<GridCacheOperation, CacheObject> entryProcRes = tx.entry(txKey()).entryProcessorCalculatedValue(); if (lockedBy(tx.xidVersion())) obsoleteVer = tx.xidVersion(); else if (log.isDebugEnabled()) log.debug("Obsolete version was not set because lock was explicit: " + this); internal, partition(), tx.local(), false, updateCntr0,
boolean read ) throws GridCacheEntryRemovedException, GridDistributedLockCancelledException { if (tx.local()) tx.threadId(), tx.xidVersion(), tx.topologyVersion(), timeout, /*reenter*/false, /*tx*/true, tx.implicitSingle(), read) != null; tx.nodeId(), tx.otherNodeId(), tx.threadId(), tx.xidVersion(), /*tx*/true, tx.implicitSingle(), tx.ownedVersion(txKey()) );
boolean read ) throws GridCacheEntryRemovedException, GridDistributedLockCancelledException { if (tx.local()) { GridDhtTxLocalAdapter dhtTx = (GridDhtTxLocalAdapter)tx; dhtTx.nearNodeId(), dhtTx.nearXidVersion(), tx.topologyVersion(), tx.threadId(), tx.xidVersion(), serOrder, timeout, /*reenter*/false, /*tx*/true, tx.implicitSingle(), read) != null; tx.nodeId(), tx.otherNodeId(), tx.threadId(), tx.xidVersion(), /*tx*/true, tx.implicit(), null);
if (txIdMap.remove(tx.xidVersion(), tx)) { unlockMultiple(tx, tx.writeEntries()); unlockMultiple(tx, tx.readEntries()); if (!tx.alternateVersions().isEmpty()) for (GridCacheVersion ver : tx.alternateVersions()) idMap.remove(ver); if (!tx.dht() && tx.local()) { if (!tx.system()) cctx.txMetrics().onTxRollback(); tx.txState().onTxEnd(cctx, tx, false);
boolean addDepInfo ) { super(tx.xidVersion(), 0, addDepInfo); writeVer = tx.writeVersion(); threadId = tx.threadId(); concurrency = tx.concurrency(); isolation = tx.isolation(); txSize = tx.size(); plc = tx.ioPolicy(); this.txNodes = txNodes; setFlag(tx.system(), SYSTEM_TX_FLAG_MASK); setFlag(retVal, NEED_RETURN_VALUE_FLAG_MASK); setFlag(tx.isInvalidate(), INVALIDATE_FLAG_MASK); setFlag(onePhaseCommit, ONE_PHASE_COMMIT_FLAG_MASK); setFlag(last, LAST_REQ_FLAG_MASK);
CacheObject old; final boolean valid = valid(tx != null ? tx.topologyVersion() : topVer); assert tx == null || (!tx.local() && tx.onePhaseCommit()) || tx.ownsLock(this) : "Transaction does not own lock for update [entry=" + this + ", tx=" + tx + ']'; nextVersion() : tx.writeVersion(); deletedUnlocked(false); updateCntr0 = nextPartitionCounter(topVer, tx == null || tx.local(), updateCntr); cctx.cache().metrics0().onWrite(); T2<GridCacheOperation, CacheObject> entryProcRes = tx.entry(txKey()).entryProcessorCalculatedValue(); internal, partition(), tx.local(), false, updateCntr0,
if ((t = txIdMap.putIfAbsent(tx.xidVersion(), tx)) == null) { if (tx.local() && !tx.dht()) { assert tx instanceof GridNearTxLocal : tx; if (!tx.implicit()) { if (cacheCtx == null || !cacheCtx.systemTx()) threadMap.put(tx.threadId(), tx); else sysThreadMap.put(new TxThreadKey(tx.threadId(), cacheCtx.cacheId()), tx); mappedVers.put(from, tx.xidVersion()); log.debug("Added transaction version mapping [from=" + from + ", to=" + tx.xidVersion() + ", tx=" + tx + ']');
continue; IgniteTxState state = tx.txState(); if (tx.pessimistic()) { GridDhtColocatedLockFuture fut = (GridDhtColocatedLockFuture)mvccFuture(tx, GridDhtColocatedLockFuture.class); tx.nearXidVersion(), tx.nodeId(), tx.threadId(), TxLock.OWNERSHIP_REQUESTED);
/** * Handles prepare stage. * * @param tx Transaction to prepare. * @param entries Entries to lock or {@code null} if use default {@link IgniteInternalTx#optimisticLockEntries()}. * @throws IgniteCheckedException If preparation failed. */ public void prepareTx(IgniteInternalTx tx, @Nullable Collection<IgniteTxEntry> entries) throws IgniteCheckedException { if (tx.state() == MARKED_ROLLBACK) { if (tx.remainingTime() == -1) throw new IgniteTxTimeoutCheckedException("Transaction timed out: " + this); throw new IgniteCheckedException("Transaction is marked for rollback: " + tx); } // One-phase commit tx cannot timeout on prepare because it is expected to be committed. if (tx.remainingTime() == -1 && !tx.onePhaseCommit()) { tx.setRollbackOnly(); throw new IgniteTxTimeoutCheckedException("Transaction timed out: " + this); } if (tx.pessimistic() && tx.local()) return; // Nothing else to do in pessimistic mode. // Optimistic. assert tx.optimistic() || !tx.local(); if (!lockMultiple(tx, entries != null ? entries : tx.optimisticLockEntries())) { tx.setRollbackOnly(); throw new IgniteTxOptimisticCheckedException("Failed to prepare transaction (lock conflict): " + tx); } }
/** * @param tx Transaction to clear. */ public void clearThreadMap(IgniteInternalTx tx) { if (tx.local() && !tx.dht()) { assert tx instanceof GridNearTxLocal : tx; if (!tx.system()) threadMap.remove(tx.threadId(), tx); else { Integer cacheId = tx.txState().firstCacheId(); if (cacheId != null) sysThreadMap.remove(new TxThreadKey(tx.threadId(), cacheId), tx); else { for (Iterator<IgniteInternalTx> it = sysThreadMap.values().iterator(); it.hasNext(); ) { IgniteInternalTx txx = it.next(); if (tx == txx) { it.remove(); break; } } } } } }