1

我偶尔会在我们的生产服务器上遇到这个异常:

System.ArgumentNullException: Value cannot be null.
   at System.Threading.Monitor.Enter(Object obj)
   at System.Data.ProviderBase.DbConnectionPool.TransactedConnectionPool.TransactionEnded(Transaction transaction, DbConnectionInternal transactedObject)
   at System.Data.SqlClient.SqlDelegatedTransaction.SinglePhaseCommit(SinglePhaseEnlistment enlistment)
   at System.Transactions.TransactionStateDelegatedCommitting.EnterState(InternalTransaction tx)
   at System.Transactions.CommittableTransaction.Commit()
   at System.Transactions.TransactionScope.InternalDispose()
   at System.Transactions.TransactionScope.Dispose()
   //... continues here with references to my DAL code

发生此异常的原因是什么?

我已经对此进行了一些研究,但还没有取得具体的成功。我也在这里阅读了这个问题:

现在我知道,如果我能避免将我的交易升级到 DTC,我就会摆脱这个问题。但如果我不能呢?我有多个数据库要在一个事务中更新或读取,所以我必须使用 DTC。我偶尔会在通常运行良好的操作上收到此错误。

技术背景

  • 它是 .NET 3.5 上的 ASP MVC2 和 LINQ2SQL 应用程序
  • 我们有三个基于 IP 地址的负载平衡虚拟机,每个都有 IIS7
  • 使用 SQL Server 2008 的单一虚拟机 - 它由 Web 服务器共享

我应该指出,我也无法在我的开发机器(开发服务器 + SQL express 2008)和我们的测试机器(与单个 IIS7 和 SQL server 2008 一起虚拟)上重现此异常。

我怀疑我们的生产服务器配置存在一些线程/处理问题(就像两个进程试图使用相同的连接)。

更新

我找到了另一个链接。它说明 ado.net 连接处理错误可能又回来了。但遗憾的是最终没有解决方案,我发现没有其他人描述类似的问题。

4

3 回答 3

2

根据 http://support.microsoft.com/kb/960754,System.Data.dll 的 2.50727.4016 版本存在问题。

如果您的服务器有这个旧版本,我会尝试从 Microsoft 获取更新的版本。

于 2012-11-21T07:05:24.657 回答
1

它看起来像一个错误,因为它是 .NET 内部代码,与您自己的代码无关。

如果您使用反射器(或任何其他 IL 工具)查看内部TransactedConnectionPool.TransactionEnded方法,您会发现它的实现在 .NET 3 和 .NET 4 之间发生了变化……我想当时它不是线程安全的。您可以尝试将其报告给Microsoft Connect

于 2012-11-12T16:20:38.867 回答
0

根据 doco MSDN System.Transactions.TransactionScope该方法是同步的,因此它使用监视器。doco 并没有说该方法是线程安全的,所以我认为您可能以某种方式从多个线程对同一个 Transaction 范围对象调用 dispose 。您可以使用 transactionscope 对象的静态属性System.Transactions.Transaction.Current来找出您所指的事务。也许在处理您的事务范围之前的日志消息可能会暴露发生这种情况的位置......

如果这不是线程问题,那么您很可能会发现一个在 .Net 中引发错误的极端案例。我发现 MSDTC 在出现问题时的行为充其量是不愉快的。

于 2012-11-12T14:17:29.597 回答