我偶尔会在我们的生产服务器上获得此异常:
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。我通常会在通常运作良好的行动中得到这个错误。
技术背景
我应该指出,我无法在我的开发机器(开发服务器+ SQL Express 2008)和我们的测试机器(虚拟单一IIS7和SQL Server 2008一起)上重现此异常。
我怀疑我们的生产服务器配置存在一些线程/处理问题(比如两个进程正在尝试使用相同的连接)。
更新
我找到了另一个链接。它表明ado.net连接配置错误可能已经回来了。但遗憾的是最终没有解决方案,我发现没有其他人描述类似的问题。
答案 0 :(得分:2)
根据 http://support.microsoft.com/kb/960754,System.Data.dll的2.50727.4016版本存在问题。
如果您的服务器有这个旧版本,我会尝试从Microsoft获得更新版本。
答案 1 :(得分:1)
它看起来像一个bug,因为它是.NET内部代码,与您自己的代码无关。
如果您在内部TransactedConnectionPool.TransactionEnded
方法上查看反射器(或任何其他IL工具),您会看到它的实现在.NET 3和.NET 4之间发生了变化...我想它不是然后是线程安全的。您可以尝试将其报告给Microsoft Connect。
答案 2 :(得分:0)
根据doco MSDN System.Transactions.TransactionScope,该方法是同步的,因此它正在使用监视器。 doco并没有说该方法是线程安全的,所以我认为你可能会以某种方式从多个线程调用相同的Transaction范围对象上的dispose。您可以使用transactionscope对象System.Transactions.Transaction.Current
的静态属性来确定要引用的事务。处理事务范围之前的日志消息可能会暴露发生这种情况的地方......
如果这不是一个线程问题,那么你就找到了一个可以解决.Net漏洞的案例。我发现MSDTC的行为在出现问题时最多不愉快。