#region License
/*
* Copyright 2002-2004 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
using System;
using System.Reflection;
using AopAlliance.Intercept;
namespace Spring.Transaction.Interceptor{
/// <summary>
/// An AOP Alliance <see cref="AopAlliance.Intercept.IMethodInterceptor"/> providing
/// declarative transaction management using the common Spring.NET transaction infrastructure.
/// </summary>
/// <remarks>
/// <p>
/// That class contains the necessary calls into Spring.NET's underlying
/// transaction API: subclasses such as this are responsible for calling
/// superclass methods such as
/// <see cref="Spring.Transaction.Interceptor.TransactionAspectSupport.CreateTransactionIfNecessary(MethodInfo, Type) "/>
/// in the correct order, in the event of normal invocation return or an exception.
/// </p>
/// <p>
/// <see cref="Spring.Transaction.Interceptor.TransactionInterceptor"/>s are thread-safe.
/// </p>
/// </remarks>
/// <author>Rod Johnson</author>
/// <author>Juergen Hoeller</author>
/// <author>Griffin Caprio (.NET)</author>
/// <author>Mark Pollack (.NET)</author>
[Serializable]
public class TransactionInterceptor : TransactionAspectSupport, IMethodInterceptor
{
/// <summary>
/// AOP Alliance invoke call that handles all transaction plumbing.
/// </summary>
/// <param name="invocation">
/// The method that is to execute in the context of a transaction.
/// </param>
/// <returns>The return value from the method invocation.</returns>
public object Invoke(IMethodInvocation invocation)
{
// Work out the target class: may be <code>null</code>.
// The TransactionAttributeSource should be passed the target class
// as well as the method, which may be from an interface.
Type targetType = ( invocation.This != null ) ? invocation.This.GetType() : null;
// If the transaction attribute is null, the method is non-transactional.
TransactionInfo txnInfo = CreateTransactionIfNecessary( invocation.Method, targetType );
object returnValue = null;
try
{
// This is an around advice.
// Invoke the next interceptor in the chain.
// This will normally result in a target object being invoked.
returnValue = invocation.Proceed();
}
catch ( Exception ex )
{
// target invocation exception
CompleteTransactionAfterThrowing( txnInfo, ex );
throw;
}
finally
{
CleanupTransactionInfo( txnInfo );
}
CommitTransactionAfterReturning( txnInfo );
return returnValue;
}
}
}
|