001: /*
002: * Copyright 2002-2007 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.springframework.transaction.support;
018:
019: import org.springframework.transaction.NestedTransactionNotSupportedException;
020: import org.springframework.transaction.SavepointManager;
021: import org.springframework.transaction.TransactionException;
022: import org.springframework.transaction.TransactionStatus;
023: import org.springframework.transaction.TransactionUsageException;
024:
025: /**
026: * Abstract base implementation of the
027: * {@link org.springframework.transaction.TransactionStatus} interface.
028: *
029: * <p>Pre-implements the handling of local rollback-only and completed flags, and
030: * delegation to an underlying {@link org.springframework.transaction.SavepointManager}.
031: * Also offers the option of a holding a savepoint within the transaction.
032: *
033: * <p>Does not assume any specific internal transaction handling, such as an
034: * underlying transaction object, and no transaction synchronization mechanism.
035: *
036: * @author Juergen Hoeller
037: * @since 1.2.3
038: * @see #setRollbackOnly()
039: * @see #isRollbackOnly()
040: * @see #setCompleted()
041: * @see #isCompleted()
042: * @see #getSavepointManager()
043: * @see SimpleTransactionStatus
044: * @see DefaultTransactionStatus
045: */
046: public abstract class AbstractTransactionStatus implements
047: TransactionStatus {
048:
049: private boolean rollbackOnly = false;
050:
051: private boolean completed = false;
052:
053: private Object savepoint;
054:
055: //---------------------------------------------------------------------
056: // Handling of current transaction state
057: //---------------------------------------------------------------------
058:
059: public void setRollbackOnly() {
060: this .rollbackOnly = true;
061: }
062:
063: /**
064: * Determine the rollback-only flag via checking both the local rollback-only flag
065: * of this TransactionStatus and the global rollback-only flag of the underlying
066: * transaction, if any.
067: * @see #isLocalRollbackOnly()
068: * @see #isGlobalRollbackOnly()
069: */
070: public boolean isRollbackOnly() {
071: return (isLocalRollbackOnly() || isGlobalRollbackOnly());
072: }
073:
074: /**
075: * Determine the rollback-only flag via checking this TransactionStatus.
076: * <p>Will only return "true" if the application called <code>setRollbackOnly</code>
077: * on this TransactionStatus object.
078: */
079: public boolean isLocalRollbackOnly() {
080: return this .rollbackOnly;
081: }
082:
083: /**
084: * Template method for determining the global rollback-only flag of the
085: * underlying transaction, if any.
086: * <p>This implementation always returns <code>false</code>.
087: */
088: public boolean isGlobalRollbackOnly() {
089: return false;
090: }
091:
092: /**
093: * Mark this transaction as completed, that is, committed or rolled back.
094: */
095: public void setCompleted() {
096: this .completed = true;
097: }
098:
099: public boolean isCompleted() {
100: return this .completed;
101: }
102:
103: //---------------------------------------------------------------------
104: // Handling of current savepoint state
105: //---------------------------------------------------------------------
106:
107: /**
108: * Set a savepoint for this transaction. Useful for PROPAGATION_NESTED.
109: * @see org.springframework.transaction.TransactionDefinition#PROPAGATION_NESTED
110: */
111: protected void setSavepoint(Object savepoint) {
112: this .savepoint = savepoint;
113: }
114:
115: /**
116: * Get the savepoint for this transaction, if any.
117: */
118: protected Object getSavepoint() {
119: return this .savepoint;
120: }
121:
122: public boolean hasSavepoint() {
123: return (this .savepoint != null);
124: }
125:
126: /**
127: * Create a savepoint and hold it for the transaction.
128: * @throws org.springframework.transaction.NestedTransactionNotSupportedException
129: * if the underlying transaction does not support savepoints
130: */
131: public void createAndHoldSavepoint() throws TransactionException {
132: setSavepoint(getSavepointManager().createSavepoint());
133: }
134:
135: /**
136: * Roll back to the savepoint that is held for the transaction.
137: */
138: public void rollbackToHeldSavepoint() throws TransactionException {
139: if (!hasSavepoint()) {
140: throw new TransactionUsageException(
141: "No savepoint associated with current transaction");
142: }
143: getSavepointManager().rollbackToSavepoint(getSavepoint());
144: setSavepoint(null);
145: }
146:
147: /**
148: * Release the savepoint that is held for the transaction.
149: */
150: public void releaseHeldSavepoint() throws TransactionException {
151: if (!hasSavepoint()) {
152: throw new TransactionUsageException(
153: "No savepoint associated with current transaction");
154: }
155: getSavepointManager().releaseSavepoint(getSavepoint());
156: setSavepoint(null);
157: }
158:
159: //---------------------------------------------------------------------
160: // Implementation of SavepointManager
161: //---------------------------------------------------------------------
162:
163: /**
164: * This implementation delegates to a SavepointManager for the
165: * underlying transaction, if possible.
166: * @see #getSavepointManager()
167: * @see org.springframework.transaction.SavepointManager
168: */
169: public Object createSavepoint() throws TransactionException {
170: return getSavepointManager().createSavepoint();
171: }
172:
173: /**
174: * This implementation delegates to a SavepointManager for the
175: * underlying transaction, if possible.
176: * @throws org.springframework.transaction.NestedTransactionNotSupportedException
177: * @see #getSavepointManager()
178: * @see org.springframework.transaction.SavepointManager
179: */
180: public void rollbackToSavepoint(Object savepoint)
181: throws TransactionException {
182: getSavepointManager().rollbackToSavepoint(savepoint);
183: }
184:
185: /**
186: * This implementation delegates to a SavepointManager for the
187: * underlying transaction, if possible.
188: * @see #getSavepointManager()
189: * @see org.springframework.transaction.SavepointManager
190: */
191: public void releaseSavepoint(Object savepoint)
192: throws TransactionException {
193: getSavepointManager().releaseSavepoint(savepoint);
194: }
195:
196: /**
197: * Return a SavepointManager for the underlying transaction, if possible.
198: * <p>Default implementation always throws a NestedTransactionNotSupportedException.
199: * @throws org.springframework.transaction.NestedTransactionNotSupportedException
200: * if the underlying transaction does not support savepoints
201: */
202: protected SavepointManager getSavepointManager() {
203: throw new NestedTransactionNotSupportedException(
204: "This transaction does not support savepoints");
205: }
206:
207: }
|