/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.transaction.support; import org.springframework.transaction.NestedTransactionNotSupportedException; import org.springframework.transaction.SavepointManager; import org.springframework.transaction.TransactionException; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.TransactionUsageException; /** * Abstract base implementation of the * {@link org.springframework.transaction.TransactionStatus} interface. * * <p>Pre-implements the handling of local rollback-only and completed flags, and * delegation to an underlying {@link org.springframework.transaction.SavepointManager}. * Also offers the option of a holding a savepoint within the transaction. * * <p>Does not assume any specific internal transaction handling, such as an * underlying transaction object, and no transaction synchronization mechanism. * * @author Juergen Hoeller * @since 1.2.3 * @see #setRollbackOnly() * @see #isRollbackOnly() * @see #setCompleted() * @see #isCompleted() * @see #getSavepointManager() * @see SimpleTransactionStatus * @see DefaultTransactionStatus */ public abstract class AbstractTransactionStatus implements TransactionStatus { private boolean rollbackOnly = false; private boolean completed = false; private Object savepoint; //--------------------------------------------------------------------- // Handling of current transaction state //--------------------------------------------------------------------- public void setRollbackOnly() { this.rollbackOnly = true; } /** * Determine the rollback-only flag via checking both the local rollback-only flag * of this TransactionStatus and the global rollback-only flag of the underlying * transaction, if any. * @see #isLocalRollbackOnly() * @see #isGlobalRollbackOnly() */ public boolean isRollbackOnly() { return (isLocalRollbackOnly() || isGlobalRollbackOnly()); } /** * Determine the rollback-only flag via checking this TransactionStatus. * <p>Will only return "true" if the application called <code>setRollbackOnly</code> * on this TransactionStatus object. */ public boolean isLocalRollbackOnly() { return this.rollbackOnly; } /** * Template method for determining the global rollback-only flag of the * underlying transaction, if any. * <p>This implementation always returns <code>false</code>. */ public boolean isGlobalRollbackOnly() { return false; } /** * Mark this transaction as completed, that is, committed or rolled back. */ public void setCompleted() { this.completed = true; } public boolean isCompleted() { return this.completed; } //--------------------------------------------------------------------- // Handling of current savepoint state //--------------------------------------------------------------------- /** * Set a savepoint for this transaction. Useful for PROPAGATION_NESTED. * @see org.springframework.transaction.TransactionDefinition#PROPAGATION_NESTED */ protected void setSavepoint(Object savepoint) { this.savepoint = savepoint; } /** * Get the savepoint for this transaction, if any. */ protected Object getSavepoint() { return this.savepoint; } public boolean hasSavepoint() { return (this.savepoint != null); } /** * Create a savepoint and hold it for the transaction. * @throws org.springframework.transaction.NestedTransactionNotSupportedException * if the underlying transaction does not support savepoints */ public void createAndHoldSavepoint() throws TransactionException { setSavepoint(getSavepointManager().createSavepoint()); } /** * Roll back to the savepoint that is held for the transaction. */ public void rollbackToHeldSavepoint() throws TransactionException { if (!hasSavepoint()) { throw new TransactionUsageException("No savepoint associated with current transaction"); } getSavepointManager().rollbackToSavepoint(getSavepoint()); setSavepoint(null); } /** * Release the savepoint that is held for the transaction. */ public void releaseHeldSavepoint() throws TransactionException { if (!hasSavepoint()) { throw new TransactionUsageException("No savepoint associated with current transaction"); } getSavepointManager().releaseSavepoint(getSavepoint()); setSavepoint(null); } //--------------------------------------------------------------------- // Implementation of SavepointManager //--------------------------------------------------------------------- /** * This implementation delegates to a SavepointManager for the * underlying transaction, if possible. * @see #getSavepointManager() * @see org.springframework.transaction.SavepointManager */ public Object createSavepoint() throws TransactionException { return getSavepointManager().createSavepoint(); } /** * This implementation delegates to a SavepointManager for the * underlying transaction, if possible. * @throws org.springframework.transaction.NestedTransactionNotSupportedException * @see #getSavepointManager() * @see org.springframework.transaction.SavepointManager */ public void rollbackToSavepoint(Object savepoint) throws TransactionException { getSavepointManager().rollbackToSavepoint(savepoint); } /** * This implementation delegates to a SavepointManager for the * underlying transaction, if possible. * @see #getSavepointManager() * @see org.springframework.transaction.SavepointManager */ public void releaseSavepoint(Object savepoint) throws TransactionException { getSavepointManager().releaseSavepoint(savepoint); } /** * Return a SavepointManager for the underlying transaction, if possible. * <p>Default implementation always throws a NestedTransactionNotSupportedException. * @throws org.springframework.transaction.NestedTransactionNotSupportedException * if the underlying transaction does not support savepoints */ protected SavepointManager getSavepointManager() { throw new NestedTransactionNotSupportedException("This transaction does not support savepoints"); } }