2010-03-10 70 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