SqlException:通信缓冲区资源上的事务死锁

16
我有一个服务器进程,必须执行大量的数据库查询,它使用TPL并行运行。一直到今天,在30分钟内崩溃了两次,并出现以下异常:

Transaction (Process ID 89) was deadlocked on communication buffer resources with another process and has been chosen as the deadlock victim. Rerun the transaction.

数据库被配置为记录任何死锁,但它没有记录任何内容,所以似乎这个死锁只发生在客户端?我没有找到任何关于这个异常的参考,除了一个msdn论坛帖子没有提供任何信息。有人看到过这个异常吗?或者知道我如何查找更多有关它的信息吗?
---> System.AggregateException: One or more errors occurred. 

---> System.Data.SqlClient.SqlException: Transaction (Process ID 89) was deadlocked on communication buffer resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()
   at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
   at System.Data.SqlClient.SqlDataReader.HasMoreRows()
   at System.Data.SqlClient.SqlDataReader.ReadInternal(Boolean setTimeout)
   at App.CoreEngine.V5.DataAccess.SqlReader.Read(String readerDescription) in C:\SourceCode\AppV1\Releases\Libraries\CoreEngine\CoreEngine.V5\DataAccess\SqlReader.cs:line 121
   at App.CoreEngine.V5.DataAccess.DataContext.ExecuteQuery(PtQuery query, ValueStore`1 store, String readerDescription) in C:\SourceCode\AppV1\Releases\Libraries\CoreEngine\CoreEngine.V5\DataAccess\DataContext.cs:line 328
   at App.CoreEngine.V5.DataAccess.DataContext.<>c__DisplayClass12.<GetCalculatedDataForCompare>b__f(Object _) in C:\SourceCode\AppV1\Releases\Libraries\CoreEngine\CoreEngine.V5\DataAccess\DataContext.cs:line 267
   at System.Threading.Tasks.Task.Execute()
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task.WaitAll(Task[] tasks, Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at App.CoreEngine.V5.DataAccess.DataContext.GetCalculatedDataForCompare() in C:\SourceCode\AppV1\Releases\Libraries\CoreEngine\CoreEngine.V5\DataAccess\DataContext.cs:line 276
   at System.Threading.Tasks.Task`1.InvokeFuture(Object futureAsObj)
   at System.Threading.Tasks.Task.Execute()
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at System.Threading.Tasks.Task`1.get_Result()
   at App.CoreEngine.V5.DataAccess.DataContext.get_CalcCompareData() in C:\SourceCode\AppV1\Releases\Libraries\CoreEngine\CoreEngine.V5\DataAccess\DataContext.cs:line 389
   at App.CoreEngine.V5.Calculation.CalculationEngine.Run() in C:\SourceCode\AppV1\Releases\Libraries\CoreEngine\CoreEngine.V5\Calculation\CalculationEngine.cs:line 243
   at App.CoreEngine.V5.Processor.Milestone.BatchRunner.Run() in C:\SourceCode\AppV1\Releases\Libraries\CoreEngine\CoreEngine.V5\Processor\Milestone\BatchRunner.cs:line 171

---> (Inner Exception #0) System.AggregateException: One or more errors occurred. 
---> System.Data.SqlClient.SqlException: Transaction (Process ID 89) was deadlocked on communication buffer resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()
   at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
   at System.Data.SqlClient.SqlDataReader.HasMoreRows()
   at System.Data.SqlClient.SqlDataReader.ReadInternal(Boolean setTimeout)
   at App.CoreEngine.V5.DataAccess.SqlReader.Read(String readerDescription) in C:\SourceCode\Releases\Libraries\CoreEngine\CoreEngine.V5\DataAccess\SqlReader.cs:line 121
   at App.CoreEngine.V5.DataAccess.DataContext.ExecuteQuery(PtQuery query, ValueStore`1 store, String readerDescription) in C:\SourceCode\AppV1\Releases\Libraries\CoreEngine\CoreEngine.V5\DataAccess\DataContext.cs:line 328
   at App.CoreEngine.V5.DataAccess.DataContext.<>c__DisplayClass12.<GetCalculatedDataForCompare>b__f(Object _) in C:\SourceCode\AppV1\Releases\Libraries\CoreEngine\CoreEngine.V5\DataAccess\DataContext.cs:line 267
   at System.Threading.Tasks.Task.Execute()
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task.WaitAll(Task[] tasks, Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at CoreEngine.V5.DataAccess.DataContext.GetCalculatedDataForCompare() in C:\SourceCode\AppV1\Releases\Libraries\CoreEngine\CoreEngine.V5\DataAccess\DataContext.cs:line 276
   at System.Threading.Tasks.Task`1.InvokeFuture(Object futureAsObj)
   at System.Threading.Tasks.Task.Execute()

编辑 - 我刚刚双重检查了发生此问题的服务器上是否打开了dbcc 1222,我运行了dbcc tracestatus并获得了以下结果:

TraceFlag   Status  Global  Session
1222    1   1   0
3605    1   1   0

而日志中没有报告死锁的任何信息


有进行任何代码更改吗?服务器补丁?您能否在还原版本上进行测试,以查看执行计划是否更改?SQL Server的版本是什么? - gbn
据我所知,没有任何更改或严重的补丁,它是SQL Server 2008 R2。 - BrandonAGr
还有一个更改是从连接字符串中删除了ConnectionTimeout,这也导致了问题,因此我们必须像这里描述的一样将ConnectionTimeout添加回去,但这似乎与此无关。 - BrandonAGr
3个回答

10

我的猜测是,执行计划现在使用了并行处理,而以前没有达到成本阈值。

尝试在查询中使用 MAXDOP 1。

编辑后附言:

你还需要跟踪标志 1204。

TF 1222 可以提供死锁图,但是对于这种“通信缓冲区资源”死锁,可能涉及的不止两个对象(我猜测这不是索引/表冲突)。请参见 http://msdn.microsoft.com/en-us/library/ms178104.aspx

还有一个未记录的跟踪标志 1205,可以在错误日志中提供更多信息。


计划肯定包括并行处理,主要问题是过去5个月中只发生了3次此类错误,因此我无法合理地重现该问题,仅更改设置将无法确定是否会再次发生。最烦人的是当死锁发生时缺乏日志记录,尽管我已经设置TraceFlag以记录死锁,并且它曾经记录过不同类型的死锁。 - BrandonAGr

2
在我的情况下,这个过程是删除一些记录,然后在一个多线程环境中插入记录到一个表中。我不得不在用于删除的列上添加一个非聚集索引,这解决了我的问题。

这对我也起作用了。(我的应用程序是多个客户端连接到一个单独的SQL服务器数据库。)有人知道为什么这样修复了问题吗? - Jeff

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接