Open Source Repository

Home /spring/spring-transaction-3.0.5 | Repository Home


org/springframework/transaction/support/AbstractTransactionStatus.java
/*
 * Copyright 2002-2009 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;
  }

  /**
   * This implementations is empty, considering flush as a no-op.
   */
  public void flush() {
  }

  /**
   * 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 savepointthrows 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 savepointthrows 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");
  }

}