【发布时间】:2012-01-27 02:36:33
【问题描述】:
一段时间以来,我一直在 Web 应用程序中使用 Spring.NET 的声明式事务,没有出现任何问题。事务建议仅应用于服务层方法。
我们最近部署了两个 WCF 服务,它们使用我们的 Spring 托管服务对象作为依赖项。我们使用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)
这些错误是间歇性的,并且似乎与当前服务器负载相关(更多用户 = 重现的可能性更高)。此外,我们在任何非 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
【问题讨论】:
标签: asp.net multithreading wcf transactions spring.net