⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 abstractplatformtransactionmanager.java

📁 Java/J2EE application framework based on [Expert One-on-One J2EE Design and Development] by Rod John
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
					else if (status.isNewTransaction()) {
						logger.debug("Initiating transaction commit");
						doCommit(defStatus);
					}
				}
				catch (UnexpectedRollbackException ex) {
					// can only be caused by doCommit
					triggerAfterCompletion(defStatus, TransactionSynchronization.STATUS_ROLLED_BACK, ex);
					throw ex;
				}
				catch (TransactionException ex) {
					// can only be caused by doCommit
					if (isRollbackOnCommitFailure()) {
						doRollbackOnCommitException(defStatus, ex);
					}
					else {
						triggerAfterCompletion(defStatus, TransactionSynchronization.STATUS_UNKNOWN, ex);
					}
					throw ex;
				}
				catch (RuntimeException ex) {
					if (!beforeCompletionInvoked) {
						triggerBeforeCompletion(defStatus, ex);
					}
					doRollbackOnCommitException(defStatus, ex);
					throw ex;
				}
				catch (Error err) {
					if (!beforeCompletionInvoked) {
						triggerBeforeCompletion(defStatus, err);
					}
					doRollbackOnCommitException(defStatus, err);
					throw err;
				}
				triggerAfterCompletion(defStatus, TransactionSynchronization.STATUS_COMMITTED, null);
			}
			finally {
				cleanupAfterCompletion(defStatus);
			}
		}
	}

	/**
	 * This implementation of rollback handles participating in existing
	 * transactions. Delegates to doRollback and doSetRollbackOnly.
	 * @see #doRollback
	 * @see #doSetRollbackOnly
	 */
	public final void rollback(TransactionStatus status) throws TransactionException {
		DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;
		try {
			try {
				triggerBeforeCompletion(defStatus, null);
				if (defStatus.hasSavepoint()) {
					if (defStatus.isDebug()) {
						logger.debug("Rolling back transaction to savepoint");
					}
					defStatus.rollbackToHeldSavepoint();
				}
				else if (status.isNewTransaction()) {
					logger.debug("Initiating transaction rollback");
					doRollback(defStatus);
				}
				else if (defStatus.getTransaction() != null) {
					if (defStatus.isDebug()) {
						logger.debug("Setting existing transaction rollback-only");
					}
					doSetRollbackOnly(defStatus);
				}
				else {
					logger.warn("Should roll back transaction but cannot - no transaction available");
				}
			}
			catch (RuntimeException ex) {
				triggerAfterCompletion(defStatus, TransactionSynchronization.STATUS_UNKNOWN, ex);
				throw ex;
			}
			catch (Error err) {
				triggerAfterCompletion(defStatus, TransactionSynchronization.STATUS_UNKNOWN, err);
				throw err;
			}
			triggerAfterCompletion(defStatus, TransactionSynchronization.STATUS_ROLLED_BACK, null);
		}
		finally {
			cleanupAfterCompletion(defStatus);
		}
	}

	/**
	 * Invoke doRollback, handling rollback exceptions properly.
	 * @param status object representing the transaction
	 * @param ex the thrown application exception or error
	 * @throws TransactionException in case of a rollback error
	 * @see #doRollback
	 */
	private void doRollbackOnCommitException(DefaultTransactionStatus status, Throwable ex)
	    throws TransactionException {
		try {
			if (status.isNewTransaction()) {
				if (status.isDebug()) {
					logger.debug("Initiating transaction rollback on commit exception", ex);
				}
				doRollback(status);
			}
		}
		catch (RuntimeException rbex) {
			logger.error("Commit exception overridden by rollback exception", ex);
			triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN, rbex);
			throw rbex;
		}
		catch (Error rberr) {
			logger.error("Commit exception overridden by rollback exception", ex);
			triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN, rberr);
			throw rberr;
		}
		triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK, ex);
	}

	/**
	 * Trigger beforeCommit callback.
	 * @param status object representing the transaction
	 */
	private void triggerBeforeCommit(DefaultTransactionStatus status) {
		if (status.isNewSynchronization()) {
			logger.debug("Triggering beforeCommit synchronization");
			for (Iterator it = TransactionSynchronizationManager.getSynchronizations().iterator(); it.hasNext();) {
				TransactionSynchronization synchronization = (TransactionSynchronization) it.next();
				synchronization.beforeCommit(status.isReadOnly());
			}
		}
	}

	/**
	 * Trigger beforeCompletion callback.
	 * @param status object representing the transaction
	 * @param ex the thrown application exception or error, or null
	 */
	private void triggerBeforeCompletion(DefaultTransactionStatus status, Throwable ex) {
		if (status.isNewSynchronization()) {
			logger.debug("Triggering beforeCompletion synchronization");
			try {
				for (Iterator it = TransactionSynchronizationManager.getSynchronizations().iterator(); it.hasNext();) {
					TransactionSynchronization synchronization = (TransactionSynchronization) it.next();
					synchronization.beforeCompletion();
				}
			}
			catch (RuntimeException tsex) {
				if (ex != null) {
					logger.error("Rollback exception overridden by synchronization exception", ex);
				}
				throw tsex;
			}
			catch (Error tserr) {
				if (ex != null) {
					logger.error("Rollback exception overridden by synchronization exception", ex);
				}
				throw tserr;
			}
		}
	}

	/**
	 * Trigger afterCompletion callback, handling exceptions properly.
	 * @param status object representing the transaction
	 * @param completionStatus completion status according to TransactionSynchronization constants
	 * @param ex the thrown application exception or error, or null
	 */
	private void triggerAfterCompletion(DefaultTransactionStatus status, int completionStatus, Throwable ex) {
		if (status.isNewSynchronization()) {
			logger.debug("Triggering afterCompletion synchronization");
			try {
				for (Iterator it = TransactionSynchronizationManager.getSynchronizations().iterator(); it.hasNext();) {
					TransactionSynchronization synchronization = (TransactionSynchronization) it.next();
					synchronization.afterCompletion(completionStatus);
				}
			}
			catch (RuntimeException tsex) {
				if (ex != null) {
					logger.error("Rollback exception overridden by synchronization exception", ex);
				}
				throw tsex;
			}
			catch (Error tserr) {
				if (ex != null) {
					logger.error("Rollback exception overridden by synchronization exception", ex);
				}
				throw tserr;
			}
		}
	}

	/**
	 * Clean up after completion, clearing synchronization if necessary,
	 * and invoking doCleanupAfterCompletion.
	 * @param status object representing the transaction
	 * @see #doCleanupAfterCompletion
	 */
	private void cleanupAfterCompletion(DefaultTransactionStatus status) {
		if (status.isNewSynchronization()) {
			TransactionSynchronizationManager.clearSynchronization();
		}
		if (status.isNewTransaction() && !status.hasSavepoint()) {
			doCleanupAfterCompletion(status.getTransaction());
		}
		if (status.getSuspendedResources() != null) {
			if (status.isDebug()) {
				logger.debug("Resuming suspended transaction");
			}
			resume(status.getTransaction(), status.getSuspendedResources());
		}
	}


	//---------------------------------------------------------------------
	// Serialization support
	//---------------------------------------------------------------------

	private void readObject(ObjectInputStream ois) throws IOException {
		// Rely on default serialization, just initialize state after deserialization.
		try {
			ois.defaultReadObject();
		}
		catch (ClassNotFoundException ex) {
			throw new IOException("Failed to deserialize [" + getClass().getName() + "] - " +
					"check that Spring transaction libraries are available on the client side: " + ex.getMessage());
		}

		// initialize transient fields
		this.logger = LogFactory.getLog(getClass());
	}


	//---------------------------------------------------------------------
	// Template methods to be implemented in subclasses
	//---------------------------------------------------------------------

	/**
	 * Return a current transaction object, i.e. a JTA UserTransaction.
	 * @return the current transaction object
	 * @throws org.springframework.transaction.CannotCreateTransactionException
	 * if transaction support is not available (e.g. no JTA UserTransaction retrievable from JNDI)
	 * @throws TransactionException in case of lookup or system errors
	 */
	protected abstract Object doGetTransaction() throws TransactionException;

	/**
	 * Check if the given transaction object indicates an existing,
	 * i.e. already begun, transaction.
	 * @param transaction transaction object returned by doGetTransaction
	 * @return if there is an existing transaction
	 * @throws TransactionException in case of system errors
	 */
	protected abstract boolean isExistingTransaction(Object transaction) throws TransactionException;

	/**
	 * Return whether to use a savepoint for a nested transaction. Default is true,
	 * which causes delegation to DefaultTransactionStatus for holding a savepoint.
	 * <p>Subclasses can override this to return false, causing a further
	 * invocation of doBegin despite an already existing transaction.
	 * @see DefaultTransactionStatus#createAndHoldSavepoint
	 * @see DefaultTransactionStatus#rollbackToHeldSavepoint
	 * @see DefaultTransactionStatus#releaseHeldSavepoint
	 * @see #doBegin
	 */
	protected boolean useSavepointForNestedTransaction() {
		return true;
	}

	/**
	 * Begin a new transaction with the given transaction definition.
	 * Does not have to care about applying the propagation behavior,
	 * as this has already been handled by this abstract manager.
	 * @param transaction transaction object returned by doGetTransaction
	 * @param definition TransactionDefinition instance, describing
	 * propagation behavior, isolation level, timeout etc.
	 * @throws TransactionException in case of creation or system errors
	 */
	protected abstract void doBegin(Object transaction, TransactionDefinition definition)
	    throws TransactionException;

	/**
	 * Suspend the resources of the current transaction.
	 * Transaction synchronization will already have been suspended.
	 * @param transaction transaction object returned by doGetTransaction
	 * @return an object that holds suspended resources
	 * (will be kept unexamined for passing it into doResume)
	 * @throws org.springframework.transaction.IllegalTransactionStateException
	 * if suspending is not supported by the transaction manager implementation
	 * @throws TransactionException in case of system errors
	 * @see #doResume
	 */
	protected abstract Object doSuspend(Object transaction) throws TransactionException;

	/**
	 * Resume the resources of the current transaction.
	 * Transaction synchronization will be resumed afterwards.
	 * @param transaction transaction object returned by doGetTransaction
	 * @param suspendedResources the object that holds suspended resources,
	 * as returned by doSuspend
	 * @throws org.springframework.transaction.IllegalTransactionStateException
	 * if resuming is not supported by the transaction manager implementation
	 * @throws TransactionException in case of system errors
	 * @see #doSuspend
	 */
	protected abstract void doResume(Object transaction, Object suspendedResources)
	    throws TransactionException;

	/**
	 * Perform an actual commit on the given transaction.
	 * An implementation does not need to check the rollback-only flag.
	 * @param status status representation of the transaction
	 * @throws TransactionException in case of commit or system errors
	 */
	protected abstract void doCommit(DefaultTransactionStatus status) throws TransactionException;

	/**
	 * Perform an actual rollback on the given transaction.
	 * An implementation does not need to check the new transaction flag.
	 * @param status status representation of the transaction
	 * @throws TransactionException in case of system errors
	 */
	protected abstract void doRollback(DefaultTransactionStatus status) throws TransactionException;

	/**
	 * Set the given transaction rollback-only. Only called on rollback
	 * if the current transaction takes part in an existing one.
	 * @param status status representation of the transaction
	 * @throws TransactionException in case of system errors
	 */
	protected abstract void doSetRollbackOnly(DefaultTransactionStatus status) throws TransactionException;

	/**
	 * Cleanup resources after transaction completion.
	 * Called after doCommit and doRollback execution on any outcome.
	 * Should not throw any exceptions but just issue warnings on errors.
	 * <p>Default implementation does nothing.
	 * @param transaction transaction object returned by doGetTransaction
	 */
	protected void doCleanupAfterCompletion(Object transaction) {
	}


	/**
	 * Holder for suspended resources.
	 * Used internally by suspend and resume.
	 * @see #suspend
	 * @see #resume
	 */
	private static class SuspendedResourcesHolder {

		private final List suspendedSynchronizations;

		private final Object suspendedResources;

		private SuspendedResourcesHolder(List suspendedSynchronizations, Object suspendedResources) {
			this.suspendedSynchronizations = suspendedSynchronizations;
			this.suspendedResources = suspendedResources;
		}

		private List getSuspendedSynchronizations() {
			return suspendedSynchronizations;
		}

		private Object getSuspendedResources() {
			return suspendedResources;
		}
	}

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -