2011-09-05 42 views
7

我使用.NET Framework 4.0,C#和SQL Server 2008 R2的Windows Server 2008 R2上。我的LINQ to SQL數據上下文位於單獨的庫中,並且有問題的代碼正在Windows服務中運行。我有一個經過良好測試的任務關鍵型存儲過程,它需要大約19個參數(我知道我知道),執行一些簡單的「if」邏輯並構建一些變量,並將數據插入到3個表中。它不使用遊標或臨時表。我已經描述了SP的功能,因爲我無權發佈sql代碼。LINQ to SQL中是否存在一個錯誤或限制,導致存儲過程超時?

我看到許多直徑大約SQLEXCEPTION互聯網由於命令超時的帖子,並響應很少超過「增加命令超時」。 Example

我得到了上述異常,因此嘗試在創建數據上下文時創建數據上下文至10分鐘。在等待那10分鐘後,我仍然得到例外。然後我添加了一些調試日誌記錄來捕獲從LINQ到SQL的輸出,並使用相同的參數值在SQL Server Management Studio中運行SP。它在第二個的分數中成功完成。

這裏的LINQ to SQL的日誌輸出(帶回到默認的超時),還有一些其他的日誌輸出混合,我已經在這個崗位混淆的SP名稱:

16:01:37 15269 Irrelevant log line, deleted for StackOverflow 
EXEC @RETURN_VALUE = [dbo].[NAMEHIDDENONSTACKOVERFLOW] @Eastings = @p0, @Northings = @p1, @Speed = @p2, @UpdateDate = @p3, @UserId = @p4, @Postion = @p5, @Direction = @p6, @VehicleId = @p7, @Status = @p8, @Confidence = @p9, @Latitude = @p10, @Longitude = @p11, @PosLatitude = @p12, @PosLongitude = @p13, @WatchBoxId = @p14, @LastWatchBoxId = @p15, @WatchBoxIdAlert = @p16, @ImbolizationState = @p17, @TowAwayAlertState = @p18 
-- @p0: Input Int (Size = -1; Prec = 0; Scale = 0) [560120] 
-- @p1: Input Int (Size = -1; Prec = 0; Scale = 0) [5754714] 
-- @p2: Input Int (Size = -1; Prec = 0; Scale = 0) [0] 
-- @p3: Input DateTime (Size = -1; Prec = 0; Scale = 0) [02/08/2011 20:45:08] 
-- @p4: Input Int (Size = -1; Prec = 0; Scale = 0) [11] 
-- @p5: Input NVarChar (Size = 4000; Prec = 0; Scale = 0) [Swindon United Kingdom] 
-- @p6: Input NVarChar (Size = 4000; Prec = 0; Scale = 0) [5] 
-- @p7: Input Int (Size = -1; Prec = 0; Scale = 0) [15269] 
-- @p8: Input Int (Size = -1; Prec = 0; Scale = 0) [901] 
-- @p9: Input Int (Size = -1; Prec = 0; Scale = 0) [0] 
-- @p10: Input Float (Size = -1; Prec = 0; Scale = 0) [51.939899] 
-- @p11: Input Float (Size = -1; Prec = 0; Scale = 0) [-2.125414] 
-- @p12: Input Float (Size = -1; Prec = 0; Scale = 0) [51.9333333] 
-- @p13: Input Float (Size = -1; Prec = 0; Scale = 0) [-2.1] 
-- @p14: Input Int (Size = -1; Prec = 0; Scale = 0) [-1] 
-- @p15: Input Int (Size = -1; Prec = 0; Scale = 0) [-1] 
-- @p16: Input Int (Size = -1; Prec = 0; Scale = 0) [0] 
-- @p17: Input Int (Size = -1; Prec = 0; Scale = 0) [0] 
-- @p18: Input Int (Size = -1; Prec = 0; Scale = 0) [0] 
-- @RETURN_VALUE: Output Int (Size = -1; Prec = 0; Scale = 0) [Null] 
-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 4.0.30319.1 

16:02:23 0 Error in DoPoll 1 Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. 

唯一的線索,我從Stack Overflow搜索得到的結果是,可能存在一個叫做「參數嗅探」的問題,但是我仍然在閱讀它來研究它的含義。

這是真正的關鍵的東西,如果它在生產中失敗,我會得到很多的麻煩,所以我很想回滾LINQ,並返回到香草ADO。我的問題是:我的方法有什麼問題(換句話說:我是白癡嗎?)還是在LINQ to SQL中有一些問題或錯誤可能導致此問題?有什麼我可以做的,以解決這個問題,還是更好地恢復到香草ADO?

+1

有幾件事情來嘗試,如果是參數嗅探:http://elegantcode.com/2008/05/17/sql-parameter-sniffing-and-what-to-do-about-it/和http: //stackoverflow.com/questions/6986607/a-5sec-sp-hitting-a-30sec-timeout-through-linq-to-sql/6986902#6986902 –

+0

http://stackoverflow.com/questions/211355/parameter- sniffing-or-spoofing-in-sql-server也相當不錯。 –

+1

+1「我知道我知道」:) – AakashM

回答

0

我恢復到vanila ADO並得到相同的異常,所以答案必須是「不是LINQ to SQL錯誤」。我也通過參數嗅探文章重構了SP,但它沒有幫助。隨着代碼再次開始工作,我只能想象這是一個臨時系統問題或數據庫故障。爲了其他有類似問題的人的利益,通過稍後搜索來查找此問題,如果我找到更多內容,我會進一步更新,因爲一名同事將很快在另一個系統上測試代碼。

編輯:這是一個系統問題;具體來說,我的VMWare磁盤需要進行碎片整理。

(每上元的建議,我應該張貼我自己的答案,而不是更新的問題)。

+0

SQL SP中有任何'IF'子句嗎?我注意到有時SQL報告1結果集,有時更多。我會試着找到我用來確定這個的代碼。 – leppie

+0

嘗試運行'exec sys.sp_procedure_params_rowset'yoursp''幾次,看看輸出是否保持不變。 – leppie

+0

是的,有一些IF子句。 –

0

LINQ到SQL底層使用ADO.NET香草。至少就ADO.NET和SQL Server而言,你無法接近他們可以處理的參數數量。只要存儲過程沒有做任何可怕的事情,比如在proc中創建動態SQL,或者從臨時表返回結果,LINQ-to-SQL就非常適合存儲過程。

你是如何創建的存儲過程的LINQ到SQL的映射?有一個在Visual Studio的SDK稱爲「SQLMETAL」創建的.dbml和的.cs,如果通過命令行開關指定,將存儲過程映射以及一個命令行的工具。它對存儲過程進行了足夠的分析,以驗證LINQ to SQL將如何處理它們,並會爲存儲的不符合其標準的過程提供錯誤消息。嘗試運行SQLMETAL,看看你收到什麼樣的消息。

+0

謝謝Cylon。我知道vanilla ADO是在封面下使用的(實際上我看到的異常是一個ADO異常),但不知道SqlMetal提供了有用的輸出,所以我會嘗試。爲了回答你的問題,我通過將存儲過程從服務器資源管理器拖放到Visual Studio 2010中的數據上下文關係圖來生成dbml。 –

+0

我一直髮現SqlMetal是一個比拖放操作更好的工具,拖放可視化工具(我認爲它是演示工具,而不是生產質量)。Linq-to-SQL確實對存儲過程有一定的限制,並且我知道SqlMetal會檢查它們。 –

+0

試過了,只有一個來自不相關db對象的警告。 –

1

我會讓你一直在努力,增加超時你的LINQ數據方面,正如你提到的,大多數你找到了帖子的建議假設。

但是......

在什麼情況下,班次很多人這個樣子是Web服務器,特別是如果你運行這個IIS7上。

Iv'e過去曾經有過這樣的情況:我花費了無數個小時追查事情,發現問題出在哪裏,只有在5秒內通過更改IIS7中服務器應用程序的超時值才能解決問題管理面板。

我並不是說這絕對是您的問題,但如果您只將Web服務器設置爲30秒(這是默認設置),則您可以整天坐在數據環境中更改超時,而且您將永遠無法到達任何地方。

如果你想試試這個,登錄到Web服務器上運行的機器,展開左側窗格中的服務器/網站,深入到你的存儲過程,從運行應用程序。

在這一點上,你有幾個地方看看。如果您返回到網站級別EG:「默認網站」並單擊它,然後單擊最右側的高級設置並展開連接限制,您可以設置整個網站的秒數。

如果您從傳統ASP文件調用SP,然後單擊您的Web應用程序,然後雙擊中間窗格中的ASP圖標,展開「限制屬性」並更改腳本超時值以適合。

最後,如果你這樣做,使用某種CGI操作,點擊您的Web應用程序,然後在CGI雙擊,並更改超時在那裏。

最後但並非最不重要,如果沒有以上的幫助下,你可以嘗試添加以下XML片段到您的應用程序的web.config文件中的適當位置,以控制.NET腳本執行超時:

<system.web> 
     <httpRuntime executionTimeout="180"/> 
    <\system.web> 

如果你不在IIS7上運行,那麼你需要查看你的服務器使用什麼控制面板進行類似的設置。

+0

感謝您提供詳細的答案,但不幸的是,IIS不是這個等式的一部分。這是一個Windows服務。 –