sql-server - 调试严重的 LINQ-to-SQL 超时

标签 sql-server linq sql-server-2005 linq-to-sql deadlock

尝试执行 LINQ (-to-SQL) 查询时遇到超时错误

System.Data.SqlClient.SqlException: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.

现在,这不仅仅是查询速度慢的情况:

  • 我在 SQL Management Studio 中运行等效的 SQL,它很快就完成了(2 秒)
  • 我将 CommandTimeout 设置为 2 分钟。
  • 当我在单元测试中执行完全相同的查询时,它成功且快速地完成。也就是说:只有当我与其他查询一起运行此查询时,才会出现此超时。超时总是发生在同一个调用中。

最后一项让我觉得我遇到了某种数据库端死锁:查询被某处的锁阻塞,并且超时时间已过,从而终止了停滞的连接。

这个想法的问题在于,我在 DataContext 中进行选择,这会导致问题。 (我确实在不同的数据库/DataContext 中发生了插入。)我也没有显式事务。这让我有点困惑:查询行为看起来完全像死锁,但我以前从未遇到过不是由某种事务隔离问题引起的死锁 - 而这里看起来并非如此(无论如何乍一看)。

我正在寻找有关如何调试此问题的建议。我应该考虑哪些因素来确定此问题的原因?

编辑

一些可能有用的注释:

  • 我正在查询引用的 View :
    • 同一数据库中的其他 View
    • 通过链接服务器指向另一个数据库中的表的同义词。
  • 此 View 使用 union 将多个查询的结果连接在一起

尾声

我最终通过重新处理我的查询解决了核心问题。原来是多次调用几个表(通过不同的 View )。重新设计的版本绕过了所有这些,并且超时消失了。

最佳答案

再次从应用程序运行您的代码,同时等待(2 分钟??)在查询窗口中运行此代码:

;with Blockers AS
(SELECT
     r.session_id AS spid
         ,r.cpu_time,r.reads,r.writes,r.logical_reads 
         ,r.blocking_session_id AS BlockingSPID
         ,LEFT(OBJECT_NAME(st.objectid, st.dbid),50) AS ShortObjectName
         ,LEFT(DB_NAME(r.database_id),50) AS DatabaseName
         ,s.program_name
         ,s.login_name
         ,OBJECT_NAME(st.objectid, st.dbid) AS ObjectName
         ,SUBSTRING(st.text, (r.statement_start_offset/2)+1,( (CASE r.statement_end_offset
                                                                   WHEN -1 THEN DATALENGTH(st.text)
                                                                   ELSE r.statement_end_offset
                                                               END - r.statement_start_offset
                                                              )/2
                                                            ) + 1
                   ) AS SQLText
     FROM sys.dm_exec_requests                          r
         JOIN sys.dm_exec_sessions                      s ON r.session_id = s.session_id
         CROSS APPLY sys.dm_exec_sql_text (sql_handle) st
     --WHERE r.session_id > 50
)
SELECT Blockers.* FROM Blockers

它将向您显示运行时的所有 block 。

关于sql-server - 调试严重的 LINQ-to-SQL 超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2420222/

相关文章:

sql-server - 为什么 SharePoint 内容数据库中的 Sites.FullUrl 为空?在哪里可以找到网站集 url?

c# - 清除DataTable中的特定列值

c# - LINQ语句优化

c# - 使用 LINQ 根据给定条件过滤 List<Point>

sql-server - 如何使用 VBScript 从数据库复制到文本文件?

c# - 完全即发即忘存储过程 C# .NET Core

sql - 如果更新了多行,Microsoft SQL Server 2005 DB 的触发事件仅触发一次?

sql - 显示前 n 条记录并合并其余行

sql - 插入临时表查询

sql-server - 如何使用事务(开始事务、提交事务)?