Update of /cvsroot/springnet/Spring.Net/src/Spring/Spring.Data/Transaction/Interceptor
In directory sc8-pr-cvs8.sourceforge.net:/tmp/cvs-serv28456/Transaction/Interceptor
Modified Files:
TransactionAspectSupport.cs TransactionInterceptor.cs
Added Files:
DelegatingTransactionAttributeWithName.cs
Log Message:
SPRNET-485 - Add logging of transaction definition name and description when creating new transaction.
Index: TransactionAspectSupport.cs
===================================================================
RCS file: /cvsroot/springnet/Spring.Net/src/Spring/Spring.Data/Transaction/Interceptor/TransactionAspectSupport.cs,v
retrieving revision 1.12
retrieving revision 1.13
diff -C2 -d -r1.12 -r1.13
*** TransactionAspectSupport.cs 16 Aug 2007 05:41:03 -0000 1.12
--- TransactionAspectSupport.cs 7 Sep 2007 04:46:53 -0000 1.13
***************
*** 25,28 ****
--- 25,30 ----
using Spring.Objects.Factory;
using Spring.Threading;
+ using Spring.Util;
+ using IsolationLevel=System.Data.IsolationLevel;
namespace Spring.Transaction.Interceptor
***************
*** 73,77 ****
private ITransactionAttribute _transactionAttribute;
! private MethodInfo _methodInfo;
private ITransactionStatus _transactionStatus;
private TransactionInfo _oldTransactionInfo;
--- 75,79 ----
private ITransactionAttribute _transactionAttribute;
! private string _joinpointIdentification;
private ITransactionStatus _transactionStatus;
private TransactionInfo _oldTransactionInfo;
***************
*** 83,91 ****
/// </summary>
/// <param name="transactionAttribute">The transaction attributes to associate with any transaction.</param>
! /// <param name="methodInfo">The method info for diagnostic display of joinpoint</param>
! public TransactionInfo( ITransactionAttribute transactionAttribute, MethodInfo methodInfo)
{
_transactionAttribute = transactionAttribute;
! _methodInfo = methodInfo;
}
--- 85,93 ----
/// </summary>
/// <param name="transactionAttribute">The transaction attributes to associate with any transaction.</param>
! /// <param name="joinpointIdentification">The info for diagnostic display of joinpoint</param>
! public TransactionInfo( ITransactionAttribute transactionAttribute, string joinpointIdentification)
{
_transactionAttribute = transactionAttribute;
! _joinpointIdentification = joinpointIdentification;
}
***************
*** 118,122 ****
public void BindToThread()
{
!
TransactionInfo currentTransactionInfo = LogicalThreadContext.GetData(CURRENT_TRANSACTIONINFO_SLOTNAME) as TransactionInfo;
_oldTransactionInfo = currentTransactionInfo;
--- 120,125 ----
public void BindToThread()
{
! // Expose current TransactionStatus, preserving any existing TransactionStatus
! // for restoration after this transaction is complete.
TransactionInfo currentTransactionInfo = LogicalThreadContext.GetData(CURRENT_TRANSACTIONINFO_SLOTNAME) as TransactionInfo;
_oldTransactionInfo = currentTransactionInfo;
***************
*** 131,134 ****
--- 134,139 ----
public void RestoreThreadLocalStatus()
{
+ // Use stack to restore old transaction TransactionInfo.
+ // Will be null if none was set.
LogicalThreadContext.SetData(CURRENT_TRANSACTIONINFO_SLOTNAME, _oldTransactionInfo);
}
***************
*** 145,153 ****
}
! public string JoinpointIdentification()
! {
! //TODO return fully qualified name.
! return _methodInfo.ToString();
! }
}
#endregion
--- 150,157 ----
}
! public string JoinpointIdentification
! {
! get { return _joinpointIdentification; }
! }
}
#endregion
***************
*** 316,361 ****
ITransactionAttribute sourceAttr = _transactionAttributeSource.ReturnTransactionAttribute( method, targetType );
! ITransactionAttribute txAttr = sourceAttr;
! if (txAttr != null && txAttr.Name == null)
! {
! //TODO assign tx name as method name
! }
! TransactionInfo transactionInfo = new TransactionInfo( txAttr, method );
! if ( txAttr != null )
! {
! // We need a transaction for this method
! #region Instrumentation
! if (log.IsDebugEnabled)
! {
! log.Debug("Getting transaction for " + transactionInfo.JoinpointIdentification());
! }
! #endregion
! // The transaction manager will flag an error if an incompatible tx already exists
! transactionInfo.TransactionStatus = _transactionManager.GetTransaction(txAttr);
! }
! else
! {
! // The TransactionInfo.HasTransaction property will return
! // false. We created it only to preserve the integrity of
! // the ThreadLocal stack maintained in this class.
! if (log.IsDebugEnabled)
! {
! log.Debug("Don't need to create transaction for [" + method +
! "]: this method isn't transactional");
! }
! }
! // We always bind the TransactionInfo to the thread, even if we didn't create
! // a new transaction here. This guarantees that the TransactionInfo stack
! // will be managed correctly even if no transaction was created by this aspect.
! transactionInfo.BindToThread( );
! return transactionInfo;
! }
! /// <summary>
/// Execute after the successful completion of call, but not after an exception was handled.
/// </summary>
--- 320,375 ----
ITransactionAttribute sourceAttr = _transactionAttributeSource.ReturnTransactionAttribute( method, targetType );
! return CreateTransactionIfNecessary(sourceAttr, MethodIdentification(method));
! }
! protected TransactionInfo CreateTransactionIfNecessary(ITransactionAttribute sourceAttr, string joinpointIdentification)
! {
! ITransactionAttribute txAttr = sourceAttr;
! if (txAttr != null && txAttr.Name == null)
! {
! txAttr = new DelegatingTransactionAttributeWithName(txAttr, joinpointIdentification);
! }
! TransactionInfo transactionInfo = new TransactionInfo(txAttr, joinpointIdentification);
! if ( txAttr != null )
! {
! // We need a transaction for this method
! #region Instrumentation
! if (log.IsDebugEnabled)
! {
! log.Debug("Getting transaction for " + transactionInfo.JoinpointIdentification);
! }
! #endregion
! // The transaction manager will flag an error if an incompatible tx already exists
! transactionInfo.TransactionStatus = _transactionManager.GetTransaction(txAttr);
! }
! else
! {
! // The TransactionInfo.HasTransaction property will return
! // false. We created it only to preserve the integrity of
! // the ThreadLocal stack maintained in this class.
! if (log.IsDebugEnabled)
! {
! log.Debug("Don't need to create transaction for [" + joinpointIdentification +
! "]: this method isn't transactional");
! }
! }
! // We always bind the TransactionInfo to the thread, even if we didn't create
! // a new transaction here. This guarantees that the TransactionInfo stack
! // will be managed correctly even if no transaction was created by this aspect.
! transactionInfo.BindToThread( );
! return transactionInfo;
! }
!
! protected string MethodIdentification(MethodInfo methodInfo)
! {
! return ObjectUtils.GetQualifiedMethodName(methodInfo);
! }
!
! /// <summary>
/// Execute after the successful completion of call, but not after an exception was handled.
/// </summary>
***************
*** 378,382 ****
if (log.IsDebugEnabled)
{
! log.Debug("Invoking commit for transaction on " + transactionInfo.JoinpointIdentification());
}
--- 392,396 ----
if (log.IsDebugEnabled)
{
! log.Debug("Invoking commit for transaction on " + transactionInfo.JoinpointIdentification);
}
***************
*** 408,412 ****
if (log.IsDebugEnabled)
{
! log.Debug("Completing transaction for [" + transactionInfo.JoinpointIdentification() + "] after exception: " + exception);
}
--- 422,426 ----
if (log.IsDebugEnabled)
{
! log.Debug("Completing transaction for [" + transactionInfo.JoinpointIdentification + "] after exception: " + exception);
}
Index: TransactionInterceptor.cs
===================================================================
RCS file: /cvsroot/springnet/Spring.Net/src/Spring/Spring.Data/Transaction/Interceptor/TransactionInterceptor.cs,v
retrieving revision 1.11
retrieving revision 1.12
diff -C2 -d -r1.11 -r1.12
*** TransactionInterceptor.cs 8 Aug 2007 19:27:46 -0000 1.11
--- TransactionInterceptor.cs 7 Sep 2007 04:46:53 -0000 1.12
***************
*** 20,23 ****
--- 20,24 ----
using System;
+ using System.Reflection;
using AopAlliance.Intercept;
***************
*** 33,37 ****
/// transaction API: subclasses such as this are responsible for calling
/// superclass methods such as
! /// <see cref="Spring.Transaction.Interceptor.TransactionAspectSupport.CreateTransactionIfNecessary"/>
/// in the correct order, in the event of normal invocation return or an exception.
/// </p>
--- 34,38 ----
/// 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>
--- NEW FILE: DelegatingTransactionAttributeWithName.cs ---
#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;
#if NET_2_0
using System.Transactions;
#endif
using IsolationLevel=System.Data.IsolationLevel;
namespace Spring.Transaction.Interceptor
{
/// <summary>
/// ITransactionAttribute that delegates all calls to a give target attribute except for the
/// name, which is specified in the constructor.
/// </summary>
public class DelegatingTransactionAttributeWithName : ITransactionAttribute
{
private ITransactionAttribute targetAttribute;
private string joinpointIdentification;
/// <summary>
/// Initializes a new instance of the <see cref="DelegatingTransactionAttributeWithName"/> class.
/// </summary>
/// <param name="targetAttribute">The target attribute.</param>
/// <param name="identification">The identification.</param>
public DelegatingTransactionAttributeWithName(ITransactionAttribute targetAttribute, string identification)
{
this.targetAttribute = targetAttribute;
joinpointIdentification = identification;
}
/// <summary>
/// Decides if rollback is required for the supplied <paramref name="exception"/>.
/// </summary>
/// <param name="exception">The <see cref="System.Exception"/> to evaluate.</param>
/// <returns>
/// True if the exception causes a rollback, false otherwise.
/// </returns>
public bool RollbackOn(Exception exception)
{
return targetAttribute.RollbackOn(exception);
}
/// <summary>
/// Return the propagation behavior of type
/// <see cref="Spring.Transaction.TransactionPropagation"/>.
/// </summary>
/// <value></value>
public TransactionPropagation PropagationBehavior
{
get { return targetAttribute.PropagationBehavior; }
}
/// <summary>
/// Return the isolation level of type <see cref="System.Data.IsolationLevel"/>.
/// </summary>
/// <value></value>
/// <remarks>
/// <p>
/// Only makes sense in combination with
/// <see cref="Spring.Transaction.TransactionPropagation.Required"/> and
/// <see cref="Spring.Transaction.TransactionPropagation.RequiresNew"/>.
/// </p>
/// <p>
/// Note that a transaction manager that does not support custom isolation levels
/// will throw an exception when given any other level than
/// <see cref="System.Data.IsolationLevel.Unspecified"/>.
/// </p>
/// </remarks>
public IsolationLevel TransactionIsolationLevel
{
get { return targetAttribute.TransactionIsolationLevel; }
}
/// <summary>
/// Return the transaction timeout.
/// </summary>
/// <value></value>
/// <remarks>
/// <p>
/// Must return a number of seconds, or -1.
/// Only makes sense in combination with
/// <see cref="Spring.Transaction.TransactionPropagation.Required"/> and
/// <see cref="Spring.Transaction.TransactionPropagation.RequiresNew"/>.
/// Note that a transaction manager that does not support timeouts will
/// throw an exception when given any other timeout than -1.
/// </p>
/// </remarks>
public int TransactionTimeout
{
get { return targetAttribute.TransactionTimeout; }
}
/// <summary>
/// Get whether to optimize as read-only transaction.
/// </summary>
/// <value></value>
/// <remarks>
/// <p>
/// This just serves as hint for the actual transaction subsystem,
/// it will <i>not necessarily</i> cause failure of write accesses.
/// </p>
/// <p>
/// Only makes sense in combination with
/// <see cref="Spring.Transaction.TransactionPropagation.Required"/> and
/// <see cref="Spring.Transaction.TransactionPropagation.RequiresNew"/>.
/// </p>
/// <p>
/// A transaction manager that cannot interpret the read-only hint
/// will <i>not</i> throw an exception when given <c>ReadOnly=true</c>.
/// </p>
/// </remarks>
public bool ReadOnly
{
get { return targetAttribute.ReadOnly; }
}
/// <summary>
/// Return the name of this transaction.
/// </summary>
/// <value></value>
/// <remarks>
/// The exposed name will be the fully
/// qualified type name + "." method name + assembly (by default).
/// </remarks>
public string Name
{
get { return joinpointIdentification; }
}
#if NET_2_0
/// <summary>
/// Gets the enterprise services interop option.
/// </summary>
/// <value>The enterprise services interop option.</value>
public EnterpriseServicesInteropOption EnterpriseServicesInteropOption
{
get { throw new NotImplementedException(); }
}
#endif
/// <summary>
/// Return a description of this transaction attribute.
/// </summary>
/// <remarks>
/// <p>
/// The format matches the one used by the
/// <see cref="Spring.Transaction.Interceptor.TransactionAttributeEditor"/>,
/// to be able to feed any result into a <see cref="Spring.Transaction.Interceptor.ITransactionAttribute"/>
/// instance's properties.
/// </p>
/// </remarks>
public override string ToString()
{
return targetAttribute.ToString();
}
}
}
|