我似乎遇到了一个奇怪的问题。在我们的服务层,我们使用WCF与nHibernate和Spring.NET 1.3.0.20349。我没有选择将spring升级到下一个版本。
我在具有AfterReturningAdvices的服务上保存方法,这些服务需要进行另一个调用Db的服务调用并使用保存对象的ID。 问题是拦截器在事务提交之前触发,这导致下一个服务调用返回空对象
经过一些阅读,我对弹簧拦截器的理解是:
我的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承诺。我不确定是否有更好的方法来解决这个问题,但似乎有效。
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;
}
}
答案 0 :(得分:1)
通过查看TransactionProxyFactoryObject的AfterPropertySet
方法的来源,我认为这实际上是应用建议的顺序。因此,您应该在预拦截器中配置AfterReturningAdvice。
如果没有调用,可能是一个错误,我建议在spring.net forums中询问。
在进行交易时调用的另一种方法是ITransactionSynchronization接口,可以在TransactionSynchronizationManager
注册。