2010-03-10 72 views
5

试图执行一个LINQ(-to-SQL)查询调试一个艰难的LINQ到SQL超时

System.Data.SqlClient.SqlException时,我得到一个超时错误:超时过期。操作完成之前超时的时间或服务器没有响应。

现在,这是不只是一个缓慢的查询的情况:

  • 我在运行SQL Management Studio中相当于SQL并迅速(2秒)完成
  • 我设置我的CommandTimeout为2分钟。
  • 当我在单元测试中执行完全相同的查询时,它成功并且快速地完成。也就是说:我只是在与其他查询一起运行此查询时才得到此超时。超时总是发生在同一个电话上。

最后一项让我觉得我得到某种数据库端死锁:查询被某处的锁阻塞,超时时间结束,导致连接停止。

这个想法的麻烦是,我只有在DataContext中做选择导致问题。 (我有插入发生在不同的数据库/ DataContexts。)我也没有明确的交易。这让我有些沮丧:查询行为看起来就像是一个死锁,但是我从来没有发生过一种并非由于某种事务隔离问题而导致的死锁 - 而且在这里看起来并不像这种情况(无论如何乍一看)。

我正在寻找关于如何调试此问题的建议。我应该考虑什么样的事情来确定造成这个问题的原因?

编辑

的一些注意事项,可能是有用的:

  • 我对查询一个观点,即引用:
    • 在同一个数据库
    • 别名指向其他意见另一个数据库中的表通过链接服务器。
  • 这种观点是使用union加入几个查询的结果一起

EPILOGUE

我结束了由返工我的查询固定的核心问题。原来不止一次地调用了几张表格(通过不同的观点)。重做版本绕过了所有这些,超时消失。

+0

当你说'我在SQL Management Studio中运行等价的SQL'时,你的意思是你是从调试输出中复制LINQ生成的实际sql吗? 另外:因为您有权访问数据库,您是否能够隔离并监视在活动监视器中运行的实际流程? – 2010-03-10 20:14:04

+0

您是否在发生问题的同时运行了SQL Profiler? – 2010-03-10 20:18:14

+0

@E Rolnicki:是的,从LINQ获取实际的SQL。 – 2010-03-10 20:41:16

回答

4

从应用程序再次运行你的代码,而它正在等待(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 

它会告诉你所有的块在运行时。

+0

这是一个很酷的查询,但我不认为我从中获得有用的信息。当我在超时之前查询执行的“暂停”期间运行它时,我得到2行。一个用于查询本身,另一个用于查询导致超时。在后者中,我得到一个BlockingSPID为0,并且在该行中没有看到任何其他信息表明哪些内容被阻止。 – 2010-03-10 20:49:43

+0

这意味着你不在等待一个锁,这是'有用的' – 2010-03-23 11:26:48

0

您确定连接池没有被未收集的资源吃掉吗?

尝试将您的SqlDataContext包装在using块中,并查看问题是否仍然存在。

+0

我的DataContext已经在使用块中,但它的生命周期正在延伸到许多数十个查询(即:应用程序的生命周期)。 如何检查未收集的资源是否存在? – 2010-03-10 20:30:46