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:
022: /**
023: * Default implementation of the {@link org.springframework.transaction.TransactionStatus}
024: * interface, used by {@link AbstractPlatformTransactionManager}. Based on the concept
025: * of an underlying "transaction object".
026: *
027: * <p>Holds all status information that {@link AbstractPlatformTransactionManager}
028: * needs internally, including a generic transaction object determined by the
029: * concrete transaction manager implementation.
030: *
031: * <p>Supports delegating savepoint-related methods to a transaction object
032: * that implements the {@link SavepointManager} interface.
033: *
034: * <p><b>NOTE:</b> This is <i>not</i> intended to be used for other
035: * PlatformTransactionManager implementations, in particular not for
036: * mock transaction managers. Use {@link SimpleTransactionStatus} or
037: * a mock for the plain TransactionStatus interface instead.
038: *
039: * @author Juergen Hoeller
040: * @since 19.01.2004
041: * @see AbstractPlatformTransactionManager
042: * @see org.springframework.transaction.SavepointManager
043: * @see #getTransaction
044: * @see #createSavepoint
045: * @see #rollbackToSavepoint
046: * @see #releaseSavepoint
047: * @see SimpleTransactionStatus
048: */
049: public class DefaultTransactionStatus extends AbstractTransactionStatus {
050:
051: private final Object transaction;
052:
053: private final boolean newTransaction;
054:
055: private final boolean newSynchronization;
056:
057: private final boolean readOnly;
058:
059: private final boolean debug;
060:
061: private final Object suspendedResources;
062:
063: /**
064: * Create a new DefaultTransactionStatus instance.
065: * @param transaction underlying transaction object that can hold
066: * state for the internal transaction implementation
067: * @param newTransaction if the transaction is new,
068: * else participating in an existing transaction
069: * @param newSynchronization if a new transaction synchronization
070: * has been opened for the given transaction
071: * @param readOnly whether the transaction is read-only
072: * @param debug should debug logging be enabled for the handling of this transaction?
073: * Caching it in here can prevent repeated calls to ask the logging system whether
074: * debug logging should be enabled.
075: * @param suspendedResources a holder for resources that have been suspended
076: * for this transaction, if any
077: */
078: public DefaultTransactionStatus(Object transaction,
079: boolean newTransaction, boolean newSynchronization,
080: boolean readOnly, boolean debug, Object suspendedResources) {
081:
082: this .transaction = transaction;
083: this .newTransaction = newTransaction;
084: this .newSynchronization = newSynchronization;
085: this .readOnly = readOnly;
086: this .debug = debug;
087: this .suspendedResources = suspendedResources;
088: }
089:
090: /**
091: * Return the underlying transaction object.
092: */
093: public Object getTransaction() {
094: return this .transaction;
095: }
096:
097: /**
098: * Return whether there is an actual transaction active.
099: */
100: public boolean hasTransaction() {
101: return (this .transaction != null);
102: }
103:
104: public boolean isNewTransaction() {
105: return (hasTransaction() && this .newTransaction);
106: }
107:
108: /**
109: * Return if a new transaction synchronization has been opened
110: * for this transaction.
111: */
112: public boolean isNewSynchronization() {
113: return this .newSynchronization;
114: }
115:
116: /**
117: * Return if this transaction is defined as read-only transaction.
118: */
119: public boolean isReadOnly() {
120: return this .readOnly;
121: }
122:
123: /**
124: * Return whether the progress of this transaction is debugged. This is used
125: * by AbstractPlatformTransactionManager as an optimization, to prevent repeated
126: * calls to logger.isDebug(). Not really intended for client code.
127: */
128: public boolean isDebug() {
129: return this .debug;
130: }
131:
132: /**
133: * Return the holder for resources that have been suspended for this transaction,
134: * if any.
135: */
136: public Object getSuspendedResources() {
137: return this .suspendedResources;
138: }
139:
140: //---------------------------------------------------------------------
141: // Enable functionality through underlying transaction object
142: //---------------------------------------------------------------------
143:
144: /**
145: * Determine the rollback-only flag via checking both the transaction object,
146: * provided that the latter implements the SmartTransactionObject interface.
147: * <p>Will return "true" if the transaction itself has been marked rollback-only
148: * by the transaction coordinator, for example in case of a timeout.
149: * @see SmartTransactionObject#isRollbackOnly
150: */
151: public boolean isGlobalRollbackOnly() {
152: return ((this .transaction instanceof SmartTransactionObject) && ((SmartTransactionObject) this .transaction)
153: .isRollbackOnly());
154: }
155:
156: /**
157: * This implementation exposes the SavepointManager interface
158: * of the underlying transaction object, if any.
159: */
160: protected SavepointManager getSavepointManager() {
161: if (!isTransactionSavepointManager()) {
162: throw new NestedTransactionNotSupportedException(
163: "Transaction object [" + getTransaction()
164: + "] does not support savepoints");
165: }
166: return (SavepointManager) getTransaction();
167: }
168:
169: /**
170: * Return whether the underlying transaction implements the
171: * SavepointManager interface.
172: * @see #getTransaction
173: * @see org.springframework.transaction.SavepointManager
174: */
175: public boolean isTransactionSavepointManager() {
176: return (getTransaction() instanceof SavepointManager);
177: }
178:
179: }
|