2012-02-28 69 views
3

我似乎有一个奇怪的问题。在我们的服务层,我们在nHibernate和Spring.NET 1.3.0.20349中使用WCF。我没有选择升级到下一个版本。春之后回复交易提交前触发催促

我对具有AfterReturningAdvices的服务保存方法,这些服务需要进行另一个调用Db的服务调用并使用保存的对象的ID。 的问题是,提交事务,这是造成下一个服务调用返回空物体

一些阅读前后拦截器被解雇,我的温泉拦截的理解是:

  1. 预拦截beforeadvice方法运行
  2. 春季开始交易
  3. 的后拦截beforeadvice方法运行
  4. 主要服务方法运行
  5. 的后拦截afterreturning通知方法运行
  6. 春季提交事务
  7. 预拦截afterreturning通知方法运行

我的web.config有以下几点:

<object id="InsertPointcut" type="Spring.Aop.Support.NameMatchMethodPointcutAdvisor, Spring.Aop"> 
    <property name="advice"> 
     <ref local="afterAddInterceptor"/> 
    </property> 
    <property name="MappedNames"> 
     <list> 
     <value>AddToEvent</value> 
     </list> 
    </property> 
    </object> 

    <object id="UpdatePointcut" type="Spring.Aop.Support.NameMatchMethodPointcutAdvisor, Spring.Aop"> 
    <property name="advice"> 
     <ref local="afterUpdateInterceptor"/> 
    </property> 
    <property name="MappedNames"> 
     <list> 
     <value>Update</value> 
     </list> 
    </property> 
    </object> 
     <object id="ServiceProxy" type="Spring.Transaction.Interceptor.TransactionProxyFactoryObject, Spring.Data"> 
    <property name="PlatformTransactionManager" ref="transactionManager"/> 
    <property name="TransactionAttributeSource" ref="attributeTransactionAttributeSource"/> 
    <property name="target"> 
     <object id="Service" type="Service, Service" init-method="init"> 
     <constructor-arg ref="sessionFactory" /> 
     <property name="EventRepository" ref="eventRepository" /> 
     </object> 
    </property> 
    <property name="preInterceptors"> 
     <list> 
     <ref local="throwsAdvice"/> 
     <ref local="InsertPointcut"/> 
     <ref local="UpdatePointcut"/> 
     </list> 
    </property>  
    </object> 

谁能帮忙?

[更新]

为了避免代码更改我的服务,我实现了我的意见ITransactionSynchronization接口,并将其注册。这样,在AfterCompletion方法中,我可以在nHibernate已经提交的spring &之后完成我的工作。我不确定是否有更好的方法来处理这个问题,但似乎可行。

public class AfterUpdateInterceptor : IAfterReturningAdvice, ITransactionSynchronization 
{ 
    private int id; 
    [Transaction] 
    public void AfterReturning(object returnValue, MethodInfo method, object[] args, object target) 
    { 
     TransactionSynchronizationManager.RegisterSynchronization(this); 
     if (args == null || args.Length == 0) 
     { 
      return; 
     } 

     id = PropertyHelper.GetIdPropertyValue<IUpdateContract>(args); 
    } 

    public void Suspend() 
    { 
    } 

    public void Resume() 
    { 
    } 

    public void BeforeCommit(bool readOnly) 
    { 
    } 

    public void AfterCommit() 
    { 
    } 

    public void BeforeCompletion() 
    { 
    } 

    public void AfterCompletion(TransactionSynchronizationStatus status) 
    { 
     if (status != TransactionSynchronizationStatus.Committed) return;//.com msg not sent. 

     if (id > 0) 
     { 
      XmlSender.SendXmlUpdate(MessageType.Update, id); 
     } 
     id = 0; 
    } 
} 

回答

1

从看TransactionProxyFactoryObjectAfterPropertySet法的来源,我认为这实际上是在应用建议的顺序。所以你应该在你的拦截器中配置一个AfterReturningAdvice。 如果没有调用它,这可能是一个错误,我会建议在spring.net forums询问。

另一种在交易交易时被叫的方式是ITransactionSynchronization接口,它可以在TransactionSynchronizationManager上注册。

+0

建议被调用,但似乎太早调用(在提交之前)。我将研究使用TransactionSynchronizationManager – marcellscarlett 2012-02-28 21:24:23