使用TransactionScope的Intermittent System.ArgumentNullException

时间:2012-09-14 15:28:21

标签: c# .net transactionscope msdtc

我有一个Windows服务应用程序正在执行一些SQL Server调用。我有一个特定的工作单元,包括将一行保存到Message表并更新Buffer表中的多行。

我已将这两个SQL语句包装到TransactionScope中,以确保它们既可以提交,也不会被提交。

高级代码如下所示:

public static void Save(Message message)
{
    using (var transactionScope = new TransactionScope())
    {
        MessageData.Save(message.TransactionType,
                         message.Version,
                         message.CaseNumber,
                         message.RouteCode,
                         message.BufferSetIdentifier,
                         message.InternalPatientNumber,
                         message.DistrictNumber,
                         message.Data,
                         message.DateAssembled,
                         (byte)MessageState.Inserted);

        BufferLogic.FlagSetAsAssembled(message.BufferSetIdentifier);

        transactionScope.Complete();
    }
}

这一切都在我的开发机器上完美运行,并且安装了本地SQL Server。

在将Windows服务部署到服务器(但连接回本地计算机的SQL Server)时,我间歇地收到此错误消息:

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()
   at OpenLink.Logic.MessageLogic.Save(Message message) in E:\DevTFS\P0628Temp\OpenLink\OpenLink.Logic\MessageLogic.cs:line 30
   at OpenLinkMessageAssembler.OpenLinkMessageAssemblerService.RunService() in E:\DevTFS\P0628Temp\OpenLink\OpenLinkMessageAssembler\OpenLinkMessageAssemblerService.cs:line 99

我相信异常引用的代码行是using块关闭的位置,因此调用Dispose()的{​​{1}}方法。我在这里有点不知所措,因为TransactionScope类的内部工作似乎抛出了异常。

可能很重要的一点是,在服务器上安装时,我必须启用分布式事务处理协调器的一些设置以允许网络访问这让我想到当它在我的本地计算机上时,DTC是可能没用过。

DTC可以成为此异常原因的一部分吗?

我还考虑过是否要将连接池最大化,但是期望比我得到的更有用的异常。我一直在this question中运行查询以检查连接池大小,它从未超过四个。

我的最终问题是,为什么这种错误会间歇性地发生?我该如何诊断导致它的原因?

编辑:线程

@Joe建议这可能是一个线程问题。因此,我在下面列出了我的Windows服务的框架代码,看它是否有问题。

请注意,TransactionScope类仅写入Windows事件日志,并且不连接到SQL Server。

EventLogger

3 个答案:

答案 0 :(得分:0)

检查您是否已设置您的Web服务器和单独的数据库服务器,如果您将它们分开。

http://itknowledgeexchange.techtarget.com/sql-server/how-to-configure-dtc-on-windows-2008/

对于Logging我会建议把int放在事务范围内的try catch但是如果你登录到数据库你将需要使用事务范围抑制函数

 using(TransactionScope scope4 = new 
        TransactionScope(TransactionScopeOption.Suppress)) 
    {
     ...
    } 

答案 1 :(得分:0)

我通过阻止交易升级到DTC来解决这个问题。通过使用SQL 2008而不是SQL 2005,transaction does not get escalated,一切都很好。

答案 2 :(得分:0)

你没有提到你的.Net版本但根据 http://support.microsoft.com/kb/960754,System.Data.dll的2.50727.4016版本存在问题。

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