/// <summary> /// Add an attribute for a transactional method. /// </summary> /// <remarks> /// Method names can end or start with "*" for matching multiple methods. /// </remarks> /// <param name="name">The class and method name, separated by a dot.</param> /// <param name="attribute">The attribute to be associated with the method.</param> public void AddTransactionalMethod(string name, ITransactionAttribute attribute) { AssertUtils.ArgumentNotNull(name, "name"); int lastCommaIndex = name.LastIndexOf(","); if (lastCommaIndex == -1) { throw new ArgumentException("'" + name + "'" + " is not a valid method name, missing AssemblyName. Format is FQN.MethodName, AssemblyName."); } string fqnWithMethod = name.Substring(0, lastCommaIndex); int lastDotIndex = fqnWithMethod.LastIndexOf("."); if (lastDotIndex == -1) { throw new TransactionUsageException("'" + fqnWithMethod + "' is not a valid method name: format is FQN.methodName"); } string className = fqnWithMethod.Substring(0, lastDotIndex); string assemblyName = name.Substring(lastCommaIndex + 1); string methodName = fqnWithMethod.Substring(lastDotIndex + 1); string fqnClassName = className + ", " + assemblyName; try { Type type = TypeResolutionUtils.ResolveType(fqnClassName); AddTransactionalMethod(type, methodName, attribute); } catch (TypeLoadException exception) { throw new TransactionUsageException("Type '" + fqnClassName + "' not found.", exception); } }
public void DefaultTransactionAttributeToString() { DefaultTransactionAttribute source = new DefaultTransactionAttribute( ); source.PropagationBehavior = TransactionPropagation.Supports; source.TransactionIsolationLevel = IsolationLevel.RepeatableRead; source.TransactionTimeout = 10; source.ReadOnly = true; TransactionAttributeEditor editor = new TransactionAttributeEditor( ); editor.SetAsText(source.ToString( )); ITransactionAttribute ta = editor.Value; Assert.AreEqual(source, ta); Assert.AreEqual(ta.PropagationBehavior, TransactionPropagation.Supports); Assert.AreEqual(ta.TransactionIsolationLevel, IsolationLevel.RepeatableRead); Assert.AreEqual(ta.TransactionTimeout, 10); Assert.IsTrue(ta.ReadOnly); Assert.IsTrue(ta.RollbackOn(new SystemException( ))); //mlp 3/17 changed rollback to rollback on all exceptions. Assert.IsTrue(ta.RollbackOn(new ApplicationException( ))); source.TransactionTimeout = 9; Assert.IsFalse(ta == source); source.TransactionTimeout = 10; Assert.AreEqual(ta, source); }
/// <summary> /// Return the transaction attribute for this method invocation. /// </summary> /// <remarks> /// Defaults to the class's transaction attribute if no method /// attribute is found /// </remarks> /// <param name="method">method for the current invocation. Can't be null</param> /// <param name="targetType">target class for this invocation. May be null.</param> /// <returns><see cref="ITransactionAttribute"/> for this method, or null if the method is non-transactional</returns> public ITransactionAttribute ReturnTransactionAttribute(MethodInfo method, Type targetType) { object cacheKey = getCacheKey(method, targetType); lock (_transactionAttibuteCache) { object cached = _transactionAttibuteCache[cacheKey]; if (cached != null) { if (NULL_TX_ATTIBUTE == cached) { return(null); } { return((ITransactionAttribute)cached); } } else { ITransactionAttribute transactionAttribute = computeTransactionAttribute(method, targetType); if (null == transactionAttribute) { _transactionAttibuteCache.Add(cacheKey, NULL_TX_ATTIBUTE); } else { _transactionAttibuteCache.Add(cacheKey, transactionAttribute); } return(transactionAttribute); } } }
/// <summary> /// Return the transaction attribute, given this set of attributes /// attached to a method or class. Return null if it's not transactional. /// </summary> /// <remarks> /// Protected rather than private as subclasses may want to customize /// how this is done: for example, returning a /// <see cref="Spring.Transaction.Interceptor.ITransactionAttribute"/> /// affected by the values of other attributes. /// This implementation takes into account /// <see cref="Spring.Transaction.Interceptor.RollbackRuleAttribute"/>s, if /// the TransactionAttribute is a RuleBasedTransactionAttribute. /// </remarks> /// <param name="attributes"> /// Attributes attached to a method or class. May be null, in which case a null /// <see cref="Spring.Transaction.Interceptor.ITransactionAttribute"/> will be returned. /// </param> /// <returns> /// The <see cref="ITransactionAttribute"/> configured transaction attribute, or null /// if none was found. /// </returns> protected virtual ITransactionAttribute FindTransactionAttribute(Attribute[] attributes) { if (null == attributes) { return(null); } ITransactionAttribute transactionAttribute = null; foreach (Attribute currentAttribute in attributes) { transactionAttribute = currentAttribute as ITransactionAttribute; if (null != transactionAttribute) { break; } } RuleBasedTransactionAttribute ruleBasedTransactionAttribute = transactionAttribute as RuleBasedTransactionAttribute; if (null != ruleBasedTransactionAttribute) { IList rollbackRules = new LinkedList(); foreach (Attribute currentAttribute in attributes) { RollbackRuleAttribute rollbackRuleAttribute = currentAttribute as RollbackRuleAttribute; if (null != rollbackRuleAttribute) { rollbackRules.Add(rollbackRuleAttribute); } } ruleBasedTransactionAttribute.RollbackRules = rollbackRules; return(ruleBasedTransactionAttribute); } return(transactionAttribute); }
public void RuleBasedTransactionAttributeToString() { RuleBasedTransactionAttribute source = new RuleBasedTransactionAttribute(); source.PropagationBehavior = TransactionPropagation.Supports; source.TransactionIsolationLevel = IsolationLevel.RepeatableRead; source.TransactionTimeout = 10; source.ReadOnly = true; source.AddRollbackRule(new RollbackRuleAttribute("ArgumentException")); source.AddRollbackRule(new NoRollbackRuleAttribute("IllegalTransactionStateException")); TransactionAttributeEditor editor = new TransactionAttributeEditor(); editor.SetAsText(source.ToString()); ITransactionAttribute ta = editor.Value; Assert.AreEqual(source, ta); Assert.AreEqual(ta.PropagationBehavior, TransactionPropagation.Supports); Assert.AreEqual(ta.TransactionIsolationLevel, IsolationLevel.RepeatableRead); Assert.AreEqual(ta.TransactionTimeout, 10); Assert.IsTrue(ta.ReadOnly); Assert.IsTrue(ta.RollbackOn(new ArgumentException())); Assert.IsFalse(ta.RollbackOn(new IllegalTransactionStateException())); source.ClearRollbackRules(); Assert.IsFalse(ta == source); source.AddRollbackRule(new RollbackRuleAttribute("ArgumentException")); source.AddRollbackRule(new NoRollbackRuleAttribute("IllegalTransactionStateException")); Assert.AreEqual(ta, source); }
/// <summary> /// Create a transaction if necessary /// </summary> /// <param name="method">Method about to execute</param> /// <param name="targetType">Type that the method is on</param> /// <returns> /// A <see cref="Spring.Transaction.Interceptor.TransactionAspectSupport.TransactionInfo"/> object, /// whether or not a transaction was created. /// <p> /// The /// <see cref="Spring.Transaction.Interceptor.TransactionAspectSupport.TransactionInfo.HasTransaction"/> /// property on the /// <see cref="Spring.Transaction.Interceptor.TransactionAspectSupport.TransactionInfo"/> /// class can be used to tell if there was a transaction created. /// </p> /// </returns> protected TransactionInfo CreateTransactionIfNecessary(MethodInfo method, Type targetType) { // If the transaction attribute is null, the method is non-transactional. ITransactionAttribute sourceAttr = _transactionAttributeSource.ReturnTransactionAttribute(method, targetType); return(CreateTransactionIfNecessary(sourceAttr, MethodIdentification(method))); }
private void checkTransactionProperties(ITransactionAttributeSource tas, MethodInfo method, TransactionPropagation transactionPropagation) { ITransactionAttribute ta = tas.ReturnTransactionAttribute(method, null); Assert.IsTrue(ta != null); Assert.IsTrue(ta.TransactionIsolationLevel == IsolationLevel.ReadCommitted); Assert.IsTrue(ta.PropagationBehavior == transactionPropagation); }
public void EmptyStringTest() { TransactionAttributeEditor editor = new TransactionAttributeEditor( ); editor.SetAsText(String.Empty); ITransactionAttribute ta = editor.Value; Assert.IsNull(ta); }
public void NullTest() { TransactionAttributeEditor editor = new TransactionAttributeEditor( ); editor.SetAsText(null); ITransactionAttribute ta = editor.Value; Assert.IsNull(ta); }
/// <summary> /// Add a mapping. /// </summary> public void Add(string methodPattern, string txAttributeText) { TransactionAttributeEditor editor = new TransactionAttributeEditor(); editor.SetAsText(txAttributeText); ITransactionAttribute txAttribute = editor.Value; AddTransactionMethod(methodPattern, txAttribute); }
/// <summary> /// Add an attribute for a transactional method. /// </summary> /// <remarks> /// <p> /// Method names can end with "*" for matching multiple methods. /// </p> /// </remarks> /// <param name="methodName">The transactional method name.</param> /// <param name="attribute"> /// The attribute to be associated with the method. /// </param> public void AddTransactionMethod(string methodName, ITransactionAttribute attribute) { #region Instrumentation if (log.IsDebugEnabled) { log.Debug("Adding transactional method [" + methodName + "] with attribute [" + attribute + "]"); } #endregion nameMap.Add(methodName, attribute); }
public void NameMatchTransactionAttributeSourceWithEmptyMethodName() { NameMatchTransactionAttributeSource tas = new NameMatchTransactionAttributeSource(); NameValueCollection attributes = new NameValueCollection(); attributes.Add("", "PROPAGATION_MANDATORY"); tas.NameProperties = attributes; ITransactionAttribute ta = tas.ReturnTransactionAttribute(typeof(object).GetMethod("GetHashCode"), null); Assert.IsNull(ta); }
public void ValidPropagationCodeAndIsolationCode() { TransactionAttributeEditor editor = new TransactionAttributeEditor( ); editor.SetAsText("PROPAGATION_REQUIRED, ISOLATION_READUNCOMMITTED"); ITransactionAttribute ta = editor.Value; Assert.IsTrue(ta != null); Assert.IsTrue(ta.PropagationBehavior == TransactionPropagation.Required); Assert.IsTrue(ta.TransactionIsolationLevel == IsolationLevel.ReadUncommitted); }
public void NameMatchTransactionAttributeSourceWithStarAtEndOfMethodName() { NameMatchTransactionAttributeSource tas = new NameMatchTransactionAttributeSource(); NameValueCollection attributes = new NameValueCollection(); attributes.Add("GetHashCod*", "PROPAGATION_REQUIRED"); tas.NameProperties = attributes; ITransactionAttribute ta = tas.ReturnTransactionAttribute(typeof(object).GetMethod("GetHashCode"), null); Assert.IsNotNull(ta); Assert.AreEqual(TransactionPropagation.Required, ta.PropagationBehavior); }
public void ValidPropagationCodeOnly() { TransactionAttributeEditor editor = new TransactionAttributeEditor( ); editor.SetAsText("PROPAGATION_REQUIRED"); ITransactionAttribute ta = editor.Value; Assert.IsTrue(ta != null); Assert.IsTrue(ta.PropagationBehavior == TransactionPropagation.Required); Assert.IsTrue(ta.TransactionIsolationLevel == IsolationLevel.ReadCommitted); Assert.IsFalse(ta.ReadOnly); }
public void NameMatchTransactionAttributeSourceMostSpecificMethodNameIsDefinitelyMatched() { NameMatchTransactionAttributeSource tas = new NameMatchTransactionAttributeSource(); NameValueCollection attributes = new NameValueCollection(); attributes.Add("*", "PROPAGATION_REQUIRED"); attributes.Add("GetHashCode", "PROPAGATION_MANDATORY"); tas.NameProperties = attributes; ITransactionAttribute ta = tas.ReturnTransactionAttribute(typeof(object).GetMethod("GetHashCode"), null); Assert.IsNotNull(ta); Assert.AreEqual(TransactionPropagation.Mandatory, ta.PropagationBehavior); }
public void GetTransactionAttribute() { MatchAlwaysTransactionAttributeSource tas = new MatchAlwaysTransactionAttributeSource(); ITransactionAttribute ta = tas.ReturnTransactionAttribute(typeof(Object).GetMethod("GetHashCode"), null); Assert.IsNotNull(ta); Assert.IsTrue(TransactionPropagation.Required == ta.PropagationBehavior); tas.TransactionAttribute = new DefaultTransactionAttribute(TransactionPropagation.Supports); ta = tas.ReturnTransactionAttribute(typeof(DataException).GetType().GetMethod("GetHashCode"), typeof(DataException)); Assert.IsNotNull(ta); Assert.IsTrue(TransactionPropagation.Supports == ta.PropagationBehavior); }
private ITransactionAttribute getTransactionAttribute(MethodInfo methodInfo) { ITransactionAttribute transactionAttribute = FindTransactionAttribute(FindAllAttributes(methodInfo)); if (null != transactionAttribute) { return(transactionAttribute); } transactionAttribute = FindTransactionAttribute(FindAllAttributes(methodInfo.DeclaringType)); if (null != transactionAttribute) { return(transactionAttribute); } return(null); }
private ITransactionAttribute computeTransactionAttribute(MethodInfo method, Type targetType) { MethodInfo specificMethod; if (targetType == null) { specificMethod = method; } else { ParameterInfo[] parameters = method.GetParameters(); ComposedCriteria searchCriteria = new ComposedCriteria(); searchCriteria.Add(new MethodNameMatchCriteria(method.Name)); searchCriteria.Add(new MethodParametersCountCriteria(parameters.Length)); #if NET_2_0 searchCriteria.Add(new MethodGenericArgumentsCountCriteria( method.GetGenericArguments().Length)); #endif searchCriteria.Add(new MethodParametersCriteria(ReflectionUtils.GetParameterTypes(parameters))); MemberInfo[] matchingMethods = targetType.FindMembers( MemberTypes.Method, BindingFlags.Instance | BindingFlags.Public, new MemberFilter(new CriteriaMemberFilter().FilterMemberByCriteria), searchCriteria); if (matchingMethods != null && matchingMethods.Length == 1) { specificMethod = matchingMethods[0] as MethodInfo; } else { specificMethod = method; } } ITransactionAttribute transactionAttribute = getTransactionAttribute(specificMethod); if (null != transactionAttribute) { return(transactionAttribute); } else if (specificMethod != method) { transactionAttribute = getTransactionAttribute(method); } return(null); }
public void NameMatchTransactionAttributeSource() { NameMatchTransactionAttributeSource tas = new NameMatchTransactionAttributeSource(); IDictionary methodMap = new Hashtable(); methodMap.Add("GetHashCode", "PROPAGATION_REQUIRED"); methodMap.Add("ToString", new DefaultTransactionAttribute(TransactionPropagation.Supports)); tas.NameMap = methodMap; ITransactionAttribute ta = tas.ReturnTransactionAttribute(typeof(object).GetMethod("GetHashCode"), null); Assert.IsNotNull(ta); Assert.AreEqual(TransactionPropagation.Required, ta.PropagationBehavior); ta = tas.ReturnTransactionAttribute(typeof(object).GetMethod("ToString"), null); Assert.IsNotNull(ta); Assert.AreEqual(TransactionPropagation.Supports, ta.PropagationBehavior); }
public void RollbackRules() { TransactionInterceptor txInterceptor = ctx.GetObject("txRollbackAdvice") as TransactionInterceptor; Assert.IsNotNull(txInterceptor); MethodInfo getDescriptionMethod = typeof(ITestObject).GetMethod("GetDescription"); MethodInfo exceptionalMethod = typeof(ITestObject).GetMethod("Exceptional"); ITransactionAttributeSource txAttrSource = txInterceptor.TransactionAttributeSource; ITransactionAttribute txAttr = txAttrSource.ReturnTransactionAttribute(getDescriptionMethod, typeof(ITestObject)); Assert.IsTrue(txAttr.RollbackOn(new System.ApplicationException())); txAttr = txAttrSource.ReturnTransactionAttribute(exceptionalMethod, typeof(ITestObject)); Assert.IsFalse(txAttr.RollbackOn(new System.ArithmeticException())); }
/// <summary> /// Add an attribute for a transactional method. /// </summary> /// <remarks> /// Method names can end or start with "*" for matching multiple methods. /// </remarks> /// <param name="type">The target interface or class.</param> /// <param name="mappedName">The mapped method name.</param> /// <param name="transactionAttribute"> /// The attribute to be associated with the method. /// </param> public void AddTransactionalMethod( Type type, string mappedName, ITransactionAttribute transactionAttribute) { // TODO address method overloading? At present this will // simply match all methods that have the given name. string name = type.Name + "." + mappedName; MethodInfo[] methods = type.GetMethods(); IList matchingMethods = new ArrayList(); for (int i = 0; i < methods.Length; i++) { if (methods[i].Name.Equals(mappedName) || IsMatch(methods[i].Name, mappedName)) { matchingMethods.Add(methods[i]); } } if (matchingMethods.Count == 0) { throw new TransactionUsageException("Couldn't find method '" + mappedName + "' on Type [" + type.Name + "]"); } // register all matching methods foreach (MethodInfo currentMethod in matchingMethods) { string regularMethodName = (string)_nameMap[currentMethod]; if (regularMethodName == null || (!regularMethodName.Equals(name) && regularMethodName.Length <= name.Length)) { // No already registered method name, or more specific // method name specification now -> (re-)register method. if (LOG.IsDebugEnabled && regularMethodName != null) { LOG.Debug("Replacing attribute for transactional method [" + currentMethod + "]: current name '" + name + "' is more specific than '" + regularMethodName + "'"); } _nameMap.Add(currentMethod, name); AddTransactionalMethod(currentMethod, transactionAttribute); } else { if (LOG.IsDebugEnabled && regularMethodName != null) { LOG.Debug("Keeping attribute for transactional method [" + currentMethod + "]: current name '" + name + "' is not more specific than '" + regularMethodName + "'"); } } } }
public void ValidPropagationCodeAndIsolationCodeAndRollbackRules1() { TransactionAttributeEditor editor = new TransactionAttributeEditor( ); editor.SetAsText("PROPAGATION_MANDATORY,ISOLATION_REPEATABLEREAD,timeout_10,-DataException,+RemotingException"); ITransactionAttribute ta = editor.Value; Assert.IsNotNull(ta); Assert.IsTrue(ta.PropagationBehavior == TransactionPropagation.Mandatory); Assert.IsTrue(ta.TransactionIsolationLevel == IsolationLevel.RepeatableRead); Assert.IsTrue(ta.TransactionTimeout == 10); Assert.IsFalse(ta.ReadOnly); Assert.IsTrue(ta.RollbackOn(new SystemException( ))); // Check for our bizarre customized rollback rules Assert.IsTrue(ta.RollbackOn(new DataException( ))); Assert.IsTrue(!ta.RollbackOn(new RemotingException( ))); }
public void ValidPropagationCodeAndIsolationCodeAndRollbackRules2() { TransactionAttributeEditor editor = new TransactionAttributeEditor( ); editor.SetAsText("+DataException,readOnly,ISOLATION_READCOMMITTED,-RemotingException,PROPAGATION_SUPPORTS"); ITransactionAttribute ta = editor.Value; Assert.IsNotNull(ta); Assert.IsTrue(ta.PropagationBehavior == TransactionPropagation.Supports); Assert.IsTrue(ta.TransactionIsolationLevel == IsolationLevel.ReadCommitted); Assert.IsTrue(ta.TransactionTimeout == -1); Assert.IsTrue(ta.ReadOnly); Assert.IsTrue(ta.RollbackOn(new SystemException( ))); // Check for our bizarre customized rollback rules Assert.IsFalse(ta.RollbackOn(new DataException( ))); Assert.IsTrue(ta.RollbackOn(new RemotingException( ))); }
/// <summary> /// Creates the transaction if necessary. /// </summary> /// <param name="sourceAttr">The source transaction attribute.</param> /// <param name="joinpointIdentification">The joinpoint identification.</param> /// <returns>Transaction Info for declarative transaction management.</returns> protected TransactionInfo CreateTransactionIfNecessary(ITransactionAttribute sourceAttr, string joinpointIdentification) { ITransactionAttribute txAttr = sourceAttr; // If no name specified, apply method identification as transaction name. 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("Skipping transactional joinpoint [" + joinpointIdentification + "] because no transaction manager has been configured"); } } // 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> /// Parses the input properties <see cref="System.String"/> into a valid /// <see cref="Spring.Transaction.Interceptor.ITransactionAttributeSource"/> /// instance /// </summary> /// <param name="attributeSource">The properties string to be parsed.</param> public void SetAsText(string attributeSource) { MethodMapTransactionAttributeSource source = new MethodMapTransactionAttributeSource(); if (attributeSource == null || attributeSource.Length == 0) { _attributeSource = null; } else { PropertiesEditor editor = new PropertiesEditor(attributeSource); TransactionAttributeEditor tae = new TransactionAttributeEditor(); foreach (string name in editor.Keys) { string value = editor[name]; tae.SetAsText(value); ITransactionAttribute transactionAttribute = tae.Value; source.AddTransactionalMethod(name, transactionAttribute); } } _attributeSource = source; }
/// <summary> /// Return the <see cref="Spring.Transaction.Interceptor.ITransactionAttribute"/> for this /// method. /// </summary> /// <param name="method">The method to check.</param> /// <param name="targetType"> /// The target <see cref="System.Type"/>. May be null, in which case the declaring /// class of the supplied <paramref name="method"/> must be used. /// </param> /// <returns> /// A <see cref="Spring.Transaction.Interceptor.ITransactionAttribute"/> or /// null if the method is non-transactional. /// </returns> public ITransactionAttribute ReturnTransactionAttribute(MethodInfo method, Type targetType) { string methodName = method.Name; ITransactionAttribute attribute = (ITransactionAttribute)nameMap[methodName]; if (attribute != null) { return(attribute); } else { string bestNameMatch = null; foreach (string mappedName in nameMap.Keys) { if ((IsMatch(methodName, mappedName)) && (bestNameMatch == null || bestNameMatch.Length <= mappedName.Length)) { attribute = (ITransactionAttribute)nameMap[mappedName]; bestNameMatch = mappedName; } } } return(attribute); }
/// <summary> /// Add an attribute for a transactional method. /// </summary> /// <remarks> /// Method names can end or start with "*" for matching multiple methods. /// </remarks> /// <param name="type">The target interface or class.</param> /// <param name="mappedName">The mapped method name.</param> /// <param name="transactionAttribute"> /// The attribute to be associated with the method. /// </param> public void AddTransactionalMethod( Type type, string mappedName, ITransactionAttribute transactionAttribute ) { // TODO address method overloading? At present this will // simply match all methods that have the given name. string name = type.Name + "." + mappedName; MethodInfo[] methods = type.GetMethods(); IList matchingMethods = new ArrayList(); for ( int i = 0; i < methods.Length; i++ ) { if ( methods[i].Name.Equals( mappedName ) || IsMatch(methods[i].Name, mappedName )) { matchingMethods.Add( methods[i] ); } } if ( matchingMethods.Count == 0 ) { throw new TransactionUsageException("Couldn't find method '" + mappedName + "' on Type [" + type.Name + "]"); } // register all matching methods foreach ( MethodInfo currentMethod in matchingMethods ) { string regularMethodName = (string)_nameMap[currentMethod]; if ( regularMethodName == null || ( !regularMethodName.Equals(name) && regularMethodName.Length <= name.Length)) { // No already registered method name, or more specific // method name specification now -> (re-)register method. if (LOG.IsDebugEnabled && regularMethodName != null) { LOG.Debug("Replacing attribute for transactional method [" + currentMethod + "]: current name '" + name + "' is more specific than '" + regularMethodName + "'"); } _nameMap.Add( currentMethod, name ); AddTransactionalMethod( currentMethod, transactionAttribute ); } else { if (LOG.IsDebugEnabled && regularMethodName != null) { LOG.Debug("Keeping attribute for transactional method [" + currentMethod + "]: current name '" + name + "' is not more specific than '" + regularMethodName + "'"); } } } }
/// <summary> /// Add an attribute for a transactional method. /// </summary> /// <remarks> /// <p> /// Method names can end with "*" for matching multiple methods. /// </p> /// </remarks> /// <param name="methodName">The transactional method name.</param> /// <param name="attribute"> /// The attribute to be associated with the method. /// </param> public void AddTransactionMethod( string methodName, ITransactionAttribute attribute ) { #region Instrumentation if (log.IsDebugEnabled) { log.Debug("Adding transactional method [" + methodName + "] with attribute [" + attribute + "]"); } #endregion nameMap.Add( methodName, attribute ); }
/// <summary> /// Add a mapping. /// </summary> public void Add(string methodPattern, ITransactionAttribute txAttribute) { AddTransactionMethod(methodPattern, txAttribute); }
/// <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> /// Add an attribute for a transactional method. /// </summary> /// <remarks> /// Method names can end or start with "*" for matching multiple methods. /// </remarks> /// <param name="name">The class and method name, separated by a dot.</param> /// <param name="attribute">The attribute to be associated with the method.</param> public void AddTransactionalMethod( string name, ITransactionAttribute attribute ) { AssertUtils.ArgumentNotNull(name, "name"); int lastCommaIndex = name.LastIndexOf( "," ); if (lastCommaIndex == -1) { throw new ArgumentException("'" + name + "'" + " is not a valid method name, missing AssemblyName. Format is FQN.MethodName, AssemblyName."); } string fqnWithMethod = name.Substring(0, lastCommaIndex); int lastDotIndex = fqnWithMethod.LastIndexOf( "." ); if ( lastDotIndex == -1 ) { throw new TransactionUsageException("'" + fqnWithMethod + "' is not a valid method name: format is FQN.methodName"); } string className = fqnWithMethod.Substring(0, lastDotIndex ); string assemblyName = name.Substring(lastCommaIndex + 1); string methodName = fqnWithMethod.Substring(lastDotIndex + 1 ); string fqnClassName = className + ", " + assemblyName; try { Type type = TypeResolutionUtils.ResolveType(fqnClassName); AddTransactionalMethod( type, methodName, attribute ); } catch ( TypeLoadException exception ) { throw new TransactionUsageException( "Type '" + fqnClassName + "' not found.", exception ); } }
/// <summary> /// Creates a new instance of the /// <see cref="Spring.Transaction.Interceptor.TransactionAspectSupport.TransactionInfo"/> /// class for the supplied <paramref name="transactionAttribute"/>. /// </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; }
/// <summary> /// Creates the transaction if necessary. /// </summary> /// <param name="sourceAttr">The source transaction attribute.</param> /// <param name="joinpointIdentification">The joinpoint identification.</param> /// <returns>Transaction Info for declarative transaction management.</returns> protected TransactionInfo CreateTransactionIfNecessary(ITransactionAttribute sourceAttr, string joinpointIdentification) { ITransactionAttribute txAttr = sourceAttr; // If no name specified, apply method identification as transaction name. 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("Skipping transactional joinpoint [" + joinpointIdentification + "] because no transaction manager has been configured"); } } // 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> /// Creates a new instance of the /// <see cref="Spring.Transaction.Interceptor.MatchAlwaysTransactionAttributeSource"/> /// class. /// </summary> public MatchAlwaysTransactionAttributeSource() { _transactionAttribute = new DefaultTransactionAttribute(); }
public DefaultTransactionAttribute(ITransactionAttribute other) : base(other) { }
private void checkTransactionProperties(ITransactionAttributeSource tas, MethodInfo method) { ITransactionAttribute ta = tas.ReturnTransactionAttribute(method, null); Assert.IsNull(ta); }
/// <summary> /// Add an attribute for a transactional method. /// </summary> /// <param name="method">The transactional method.</param> /// <param name="transactionAttribute"> /// The attribute to be associated with the method. /// </param> public void AddTransactionalMethod( MethodInfo method, ITransactionAttribute transactionAttribute ) { _methodMap.Add( method, transactionAttribute ); }