/** * Checks transaction expiration. * * @param checkTimeout Whether timeout should be checked. * @throws IgniteCheckedException If transaction check failed. */ protected void checkValid(boolean checkTimeout) throws IgniteCheckedException { if (local() && !dht() && remainingTime() == -1 && checkTimeout) state(MARKED_ROLLBACK, true); if (isRollbackOnly()) { if (remainingTime() == -1) throw new IgniteTxTimeoutCheckedException("Cache transaction timed out: " + CU.txString(this)); TransactionState state = state(); if (state == ROLLING_BACK || state == ROLLED_BACK) throw new IgniteTxRollbackCheckedException("Cache transaction is marked as rollback-only " + "(will be rolled back automatically): " + this); if (state == UNKNOWN) throw new IgniteTxHeuristicCheckedException("Cache transaction is in unknown state " + "(remote transactions will be invalidated): " + this); throw rollbackException(); } }
/** * @param entries Entries to lock or {@code null} if use default {@link IgniteInternalTx#optimisticLockEntries()}. * @throws IgniteCheckedException If prepare step failed. */ public void userPrepare(@Nullable Collection<IgniteTxEntry> entries) throws IgniteCheckedException { if (state() != PREPARING) { if (remainingTime() == -1) throw new IgniteTxTimeoutCheckedException("Transaction timed out: " + this); TransactionState state = state(); setRollbackOnly(); throw new IgniteCheckedException("Invalid transaction state for prepare [state=" + state + ", tx=" + this + ']'); } checkValid(); try { cctx.tm().prepareTx(this, entries); calculatePartitionUpdateCounters(); } catch (IgniteCheckedException e) { throw e; } catch (Throwable e) { setRollbackOnly(); if (e instanceof Error) throw e; throw new IgniteCheckedException("Transaction validation produced a runtime exception: " + this, e); } }
/** * Commits transaction to transaction manager. Used for one-phase commit transactions only. * * @param commit If {@code true} commits transaction, otherwise rollbacks. * @param clearThreadMap If {@code true} removes {@link GridNearTxLocal} from thread map. * @param nodeStop If {@code true} tx is cancelled on node stop. * @throws IgniteCheckedException If failed. */ public void tmFinish(boolean commit, boolean nodeStop, boolean clearThreadMap) throws IgniteCheckedException { assert onePhaseCommit(); if (DONE_FLAG_UPD.compareAndSet(this, 0, 1)) { if (!nodeStop) { // Unlock all locks. if (commit) cctx.tm().commitTx(this); else cctx.tm().rollbackTx(this, clearThreadMap, false); } state(commit ? COMMITTED : ROLLED_BACK); if (commit) { boolean needsCompletedVersions = needsCompletedVersions(); assert !needsCompletedVersions || completedBase != null : "Missing completed base for transaction: " + this; assert !needsCompletedVersions || committedVers != null : "Missing committed versions for transaction: " + this; assert !needsCompletedVersions || rolledbackVers != null : "Missing rolledback versions for transaction: " + this; } cctx.mvccCaching().onTxFinished(this, commit); } }
/** {@inheritDoc} */ @Override public void userRollback(boolean clearThreadMap) throws IgniteCheckedException { TransactionState state = state(); if (state != ROLLING_BACK && state != ROLLED_BACK) { setRollbackOnly(); throw new IgniteCheckedException("Invalid transaction state for rollback [state=" + state + ", tx=" + this + ']'); } if (near()) { // Must evict near entries before rolling back from // transaction manager, so they will be removed from cache. for (IgniteTxEntry e : allEntries()) evictNearEntry(e, false); } if (DONE_FLAG_UPD.compareAndSet(this, 0, 1)) { cctx.tm().rollbackTx(this, clearThreadMap, skipCompletedVersions()); cctx.mvccCaching().onTxFinished(this, false); if (!internal()) { Collection<CacheStoreManager> stores = txState.stores(cctx); if (stores != null && !stores.isEmpty()) { assert isWriteToStoreFromDhtValid(stores) : "isWriteToStoreFromDht can't be different within one transaction"; boolean isWriteToStoreFromDht = F.first(stores).isWriteToStoreFromDht(); if (!stores.isEmpty() && (near() || isWriteToStoreFromDht)) sessionEnd(stores, false); } } } }
/** * Checks transaction expiration. * * @param checkTimeout Whether timeout should be checked. * @throws IgniteCheckedException If transaction check failed. */ protected void checkValid(boolean checkTimeout) throws IgniteCheckedException { if (local() && !dht() && remainingTime() == -1 && checkTimeout) state(MARKED_ROLLBACK, true); if (isRollbackOnly()) { if (remainingTime() == -1) throw new IgniteTxTimeoutCheckedException("Cache transaction timed out: " + CU.txString(this)); TransactionState state = state(); if (state == ROLLING_BACK || state == ROLLED_BACK) throw new IgniteTxRollbackCheckedException("Cache transaction is marked as rollback-only " + "(will be rolled back automatically): " + this); if (state == UNKNOWN) throw new IgniteTxHeuristicCheckedException("Cache transaction is in unknown state " + "(remote transactions will be invalidated): " + this); throw rollbackException(); } }
/** * @param entries Entries to lock or {@code null} if use default {@link IgniteInternalTx#optimisticLockEntries()}. * @throws IgniteCheckedException If prepare step failed. */ @SuppressWarnings({"CatchGenericClass"}) public void userPrepare(@Nullable Collection<IgniteTxEntry> entries) throws IgniteCheckedException { if (state() != PREPARING) { if (remainingTime() == -1) throw new IgniteTxTimeoutCheckedException("Transaction timed out: " + this); TransactionState state = state(); setRollbackOnly(); throw new IgniteCheckedException("Invalid transaction state for prepare [state=" + state + ", tx=" + this + ']'); } checkValid(); try { cctx.tm().prepareTx(this, entries); calculatePartitionUpdateCounters(); } catch (IgniteCheckedException e) { throw e; } catch (Throwable e) { setRollbackOnly(); if (e instanceof Error) throw e; throw new IgniteCheckedException("Transaction validation produced a runtime exception: " + this, e); } }
/** * Commits transaction to transaction manager. Used for one-phase commit transactions only. * * @param commit If {@code true} commits transaction, otherwise rollbacks. * @param clearThreadMap If {@code true} removes {@link GridNearTxLocal} from thread map. * @param nodeStop If {@code true} tx is cancelled on node stop. * @throws IgniteCheckedException If failed. */ public void tmFinish(boolean commit, boolean nodeStop, boolean clearThreadMap) throws IgniteCheckedException { assert onePhaseCommit(); if (DONE_FLAG_UPD.compareAndSet(this, 0, 1)) { if (!nodeStop) { // Unlock all locks. if (commit) cctx.tm().commitTx(this); else cctx.tm().rollbackTx(this, clearThreadMap, false); } state(commit ? COMMITTED : ROLLED_BACK); if (commit) { boolean needsCompletedVersions = needsCompletedVersions(); assert !needsCompletedVersions || completedBase != null : "Missing completed base for transaction: " + this; assert !needsCompletedVersions || committedVers != null : "Missing committed versions for transaction: " + this; assert !needsCompletedVersions || rolledbackVers != null : "Missing rolledback versions for transaction: " + this; } cctx.mvccCaching().onTxFinished(this, commit); } }
/** {@inheritDoc} */ @Override public void userRollback(boolean clearThreadMap) throws IgniteCheckedException { TransactionState state = state(); if (state != ROLLING_BACK && state != ROLLED_BACK) { setRollbackOnly(); throw new IgniteCheckedException("Invalid transaction state for rollback [state=" + state + ", tx=" + this + ']'); } if (near()) { // Must evict near entries before rolling back from // transaction manager, so they will be removed from cache. for (IgniteTxEntry e : allEntries()) evictNearEntry(e, false); } if (DONE_FLAG_UPD.compareAndSet(this, 0, 1)) { cctx.tm().rollbackTx(this, clearThreadMap, forceSkipCompletedVers); cctx.mvccCaching().onTxFinished(this, false); if (!internal()) { Collection<CacheStoreManager> stores = txState.stores(cctx); if (stores != null && !stores.isEmpty()) { assert isWriteToStoreFromDhtValid(stores) : "isWriteToStoreFromDht can't be different within one transaction"; boolean isWriteToStoreFromDht = F.first(stores).isWriteToStoreFromDht(); if (!stores.isEmpty() && (near() || isWriteToStoreFromDht)) sessionEnd(stores, false); } } } }