|
#region Licence
/*
* Copyright � 2002-2005 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.
*/
#endregion
#region Imports
using System;
using Spring.Objects.Factory;
using log4net;
using Spring.Transaction.Interceptor;
#endregion
namespace Spring.Transaction.Support
{
/// <summary>
///
/// Abstract base class that allows for easy implementation of concrete
/// platform transaction managers like JtaTransactionManager and
/// DataSourceTransactionManager.
///
/// <p>This base class provides the following workflow handling:</P>
/// <ul>
/// <li>determines if there is an existing transaction;
/// <li>applies the appropriate propagation behavior;
/// <li>suspends and resumes transactions if necessary;
/// <li>checks the rollback-only flag on commit;
/// <li>applies the appropriate modification on rollback
/// (actual rollback or setting rollback-only);
/// <li>triggers registered synchronization callbacks
/// (if transaction synchronization is active).
/// </ul>
///
/// <p>Subclasses have to implement specific template methods for specific
/// states of a transaction, for example begin, suspend, resume, commit, rollback.
/// The most important of them are abstract and must be provided by a concrete
/// implementation; for the rest, defaults are provided, so overriding is optional.
///
/// <p>Transaction synchronization is a generic mechanism for registering callbacks
/// that get invoked at transaction completion time. This is mainly used internally
/// by the data access support classes Hibernate transaction:
/// They register resources that are opened within the
/// transaction for closing at transaction completion time, allowing e.g. for reuse
/// of the same Hibernate Session within the transaction. The same mechanism can
/// also be leveraged for custom synchronization needs in an application.
///
/// <p>The state of this class is serializable, to allow for serializing the
/// transaction strategy along with proxies that carry a transaction interceptor.
/// It is up to subclasses if they wish to make their state to be serializable too.
///
/// <author> Juergen Hoeller </author>
/// <author> Moim Hossain (.NET ) </author>
/// </summary>
public abstract class AbstractPlatformTransactionManager : IPlatformTransactionManager
{
#region IPlatformTransactionManager Members
/// <summary>
///
/// </summary>
/// <param name="definition"></param>
/// <returns></returns>
public ITransactionStatus GetTransaction(ITransactionDefinition definition)
{
// The Generic Transaction Object
Object Transaction = null;
if( definition.GetPropagationBehavior() == TransactionAttribute.PROPAGATION_REQUIRES_NEW )
{ // Create a new Transacion for this thread,
Transaction = DoGetNewTransaction();
}
else if( definition.GetPropagationBehavior() == TransactionAttribute.PROPAGATION_REQUIRED )
{ // Create a new Transaction If No Transacion Exists
Transaction = DoGetTransaction();
}
else
{ // In Any Other Cases We will assume that this Object doesn't need any transaction
// support at all.
// Not Supporting Other Propagation Mode
Transaction = DoGetPropagationNeutralTransaction();
}
if( definition.GetPropagationBehavior().Equals(TransactionAttribute.PROPAGATION_REQUIRES_NEW) ||
definition.GetPropagationBehavior().Equals(TransactionAttribute.PROPAGATION_REQUIRED ))
{ // If Propagatin is transactional then Issue the transaction.
DoBegin( Transaction , definition );
}
bool FoundTransactionCreated = IsExistingTransaction( Transaction );
//
//
//
// if( IsExistingTransaction( Transaction ) )
// {
// DoBegin( Transaction , definition );
// }
// else
// {
// DoBegin( Transaction , definition );
// }
return NewTransactionStatus( Transaction , FoundTransactionCreated , false , false , false , null);
}
/// <summary>
///
/// </summary>
/// <param name="status"></param>
public void Commit(ITransactionStatus status)
{
DefaultTransactionStatus Status = (DefaultTransactionStatus)status;
DoCommit( Status );
}
/// <summary>
///
/// </summary>
/// <param name="status"></param>
public void Rollback( ITransactionStatus status )
{
DefaultTransactionStatus Status = (DefaultTransactionStatus)status;
DoRollback( Status );
}
/// <summary>
///
/// </summary>
/// <param name="status"></param>
public void Dispose( ITransactionStatus status )
{
DefaultTransactionStatus Status = (DefaultTransactionStatus)status;
DoDispose( Status );
}
#endregion
/// <summary>
///
/// </summary>
/// <param name="transaction"></param>
/// <param name="newTransaction"></param>
/// <param name="newSynchronization"></param>
/// <param name="readOnly"></param>
/// <param name="debug"></param>
/// <param name="suspendedResources"></param>
/// <returns></returns>
private ITransactionStatus NewTransactionStatus(Object transaction, bool newTransaction, bool newSynchronization, bool readOnly, bool debug, Object suspendedResources )
{
return new DefaultTransactionStatus(
transaction, newTransaction, newSynchronization, readOnly, debug, suspendedResources);
}
/// <summary>
/// Perform an actual commit of the given transaction.
/// <p>An implementation does not need to check the "new transaction" flag
/// or the rollback-only flag; this will already have been handled before.
/// Usually, a straight commit will be performed on the transaction object
/// contained in the passed-in status.</p>
/// </summary>
protected abstract void DoCommit(DefaultTransactionStatus status);
/// <summary>
/// Perform an actual rollback of the given transaction.
/// <p>An implementation does not need to check the "new transaction" flag;
/// this will already have been handled before. Usually, a straight rollback
/// will be performed on the transaction object contained in the passed-in status.</p>
/// </summary>
protected abstract void DoRollback(DefaultTransactionStatus status);
/// <summary>
/// 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.
/// </summary>
protected abstract void DoBegin(Object transaction, ITransactionDefinition definition);
/// <summary>
/// Dispose the Transaction
/// </summary>
/// <param name="status"></param>
protected abstract void DoDispose(DefaultTransactionStatus status );
//---------------------------------------------------------------------
// Template methods to be implemented in subclasses
//---------------------------------------------------------------------
/// <summary>
/// Return a transaction object for the current transaction state.
/// <p>The returned object will usually be specific to the concrete transaction
/// manager implementation, carrying corresponding transaction state in a
/// modifiable fashion. This object will be passed into the other template
/// methods (e.g. doBegin and doCommit), either directly or as part of a
/// DefaultTransactionStatus instance.
/// <p>The returned object should contain information about any existing
/// transaction, that is, a transaction that has already started before the
/// current <code>GetTransaction</code> call on the transaction manager.
/// Consequently, a <code>doGetTransaction</code> implementation will usually
/// look for an existing transaction and store corresponding state in the
/// returned transaction object.
/// </summary>
protected abstract Object DoGetTransaction() ;
/// <summary>
///
/// </summary>
/// <returns></returns>
protected abstract Object DoGetNewTransaction() ;
/// <summary>
///
/// </summary>
/// <returns></returns>
protected abstract Object DoGetPropagationNeutralTransaction();
/// <summary>
/// Check if the given transaction object indicates an existing transaction
/// (that is, a transaction which has already started).
/// <p>The result will be evaluated according to the specified propagation
/// behavior for the new transaction. An existing transaction might get
/// suspended (in case of PROPAGATION_REQUIRES_NEW), or the new transaction
/// might participate in the existing one (in case of PROPAGATION_REQUIRED).</p>
/// <p>Default implementation returns false</p>
/// <param name="transaction"></param>
/// </summary>
protected virtual bool IsExistingTransaction(Object transaction)
{
return false;
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.