WCF + Spring.NET导致间歇性的System.Transaction异常

时间:2012-01-27 02:36:33

标签: asp.net multithreading wcf transactions spring.net

我一直在Web应用程序中使用Spring.NET的声明式事务而没有问题。交易建议仅适用于服务层方法。

我们最近部署了两个使用Spring托管服务对象作为依赖项的WCF服务。我们使用Spring.ServiceModel.Activation.ServiceHostFactory根据Spring.NET示例实例化这些服务。

将这些服务部署到生产后不久,我们遇到了管理Spring事务的AdoPlatformTransactionManager类的间歇性错误。

错误文字是:

    System.ObjectDisposedException: Cannot access a disposed object.
    Object name: 'Transaction'.
       at System.Transactions.Transaction.get_IsolationLevel()
       at System.Transactions.TransactionScope..ctor(TransactionScopeOption scopeOption, TransactionOptions 
at AdoPlatformTransactionManager.DoBegin(Object transaction, ITransactionDefinition definition)
at Spring.Transaction.Support.AbstractPlatformTransactionManager.GetTransaction(ITransactionDefinition definition) 

这些错误是间歇性的,似乎与当前服务器负载相关(更多用户=更高的repro可能性)。此外,我们在任何非WCF发起的服务方法调用中都没有看到此类异常。到目前为止,我还有两个非常不稳定的理论:

  • WCF对象实例/范围(PerCall)与单例服务对象不兼容
  • 某种并发问题,其中多个WCF服务实例能够干扰其他不相关实例的环境事务(线程本地存储?)

谷歌搜索这个错误并搜索大部分空闲的Spring.NET支持论坛都没有产生任何结果,所以对任何帮助或想法表示赞赏!

更新1

进行了一些调试,并在问题上更加清晰。似乎真正的问题不是与事务相关,而是从故障状态恢复WCF信道。

在WCF方法调用期间抛出未处理的异常(在我的情况下,它是FK违规),通道似乎处于永久故障状态。

更糟糕的是,一旦某个频道进入故障状态,它会影响该服务的所有用户,因为Spring.NET不会为每个用户创建新频道。解决问题的唯一方法似乎是回收应用程序池。

基于下面引用的链接,我不确定问题是在Spring.NET中,WCF是一般的错误还是其他完全错误。

参考

client-timeout-when-using-wcf-through-spring-net

Best-Practices-and-Recover-a-Faulted-Channel

what-is-the-best-workaround-for-the-wcf-client-using-block-issue

1 个答案:

答案 0 :(得分:1)

您是否将ServiceHostFactory导出的服务声明为“原型”对象,即不是单例,以便与WCF实例正确交互?

<object id="calculator" singleton="false" type="Spring.WcfQuickStart.CalculatorService, Spring.WcfQuickStart.ServerApp">
  <property name="SleepInSeconds" value="1"/>
</object>