2014-10-16 34 views
0

每隔10分鐘就有大約300個客戶端向WCF服務發出請求。他們並非都在同一時間提出要求。x個WCF請求後的實體框架SQL超時

在服務類這LINQ查詢試圖讓configFeedItems客戶端已經尚未收到(注:我使用Ninject到存儲庫注入到我的服務類):

 var configFeedItems = (from feedItem in configFeedItemRepository.All 
          where feedItem.Id > lastReceivedFeedItemId && 
          (feedItem.TargetUserId == userId || feedItem.TargetUserId == null) && 
          !feedItem.ConfigFeedItemReceipts.Any(x => x.User.Id == userId) 
          select feedItem) 
          .ToList(); 

導致拋出這個異常:

[SqlException (0x80131904): Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.] 

這是獲取生成的SQL:

exec sp_executesql N'SELECT 
[Extent1].[Id] AS [Id], 
[Extent1].[Action] AS [Action], 
[Extent1].[TargetId] AS [TargetId], 
[Extent1].[TargetCommand] AS [TargetCommand], 
[Extent1].[CreatedOn] AS [CreatedOn], 
[Extent1].[TargetUserId] AS [TargetUserId], 
[Extent1].[ChannelToUpdate] AS [ChannelToUpdate], 
[Extent1].[CreatedBy_Id] AS [CreatedBy_Id] 
FROM [dbo].[ConfigFeedItem] AS [Extent1] 
WHERE ([Extent1].[Id] > @p__linq__0) AND ([Extent1].[TargetUserId] = @p__linq__1 OR [Extent1].[TargetUserId] IS NULL) AND (NOT EXISTS (SELECT 
1 AS [C1] 
FROM [dbo].[ConfigFeedItemReceipt] AS [Extent2] 
WHERE ([Extent1].[Id] = [Extent2].[ConfigFeedItem_Id]) AND ([Extent2].[User_Id] = @p__linq__2)))',N'@p__linq__0 int,@p__linq__1 uniqueidentifier,@p__linq__2 uniqueidentifier',@p__linq__0=0,@p__linq__1='E3D4044F-497E-4EEC-890C-021F72826505',@p__linq__2='E3D4044F-497E-4EEC-890C-021F72826505' 

如果我在IIS中停止並重新啓動AppPool,大約五分鐘就可以了,然後再次發生。

如果我改變了LINQ查詢,所以它沒有拉動ConfigFeedItemReceipts,我沒有任何超時。 它似乎只發生在我嘗試查詢子集合時。 我試過使用連接,而EF生成一個簡單的左外連接查詢,但我仍然得到一個超時。 這就像是有一個鎖或什麼的,或連接最大。

我試圖SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;執行LINQ查詢之前,但這並不有所作爲

任何想法是什麼原因造成的SQL超時?

更新:並非所有的請求都會導致超時,有些工作甚至不會發生,即使它是相同的查詢。

+0

其餘的代碼在哪裏?你在哪裏打開和*關閉*連接/交易?你是否處理了上下文?執行計劃是什麼?第二個表有'User_Id'上的索引嗎?在SQL Server的Management Studio中打開活動監視器以查看發生阻塞時的活動連接和查詢。不要 – 2014-10-16 13:14:34

+0

同樣的查詢,但不同的數據。如果'User_Id'和'ConfigFeedItem_Id'上沒有索引,則服務器必須掃描所有相關的供稿項目然後對它們進行計數。查詢的執行計劃是什麼?這張桌子有多大? – 2014-10-16 13:16:52

+0

DBContext對象的生命週期由Ninject處理,並指定爲InRequestScope()。查看執行計劃,最昂貴的95%是ConfigFeedItemReceipt(即子集合)上的關鍵查找(集羣)。是的,第二個表ConfigFeedItemReceipt在User_Id和ConfigFeedItem_Id上有一個索引。 – empo 2014-10-16 14:04:51

回答

0

我假設你正在使用代碼優先的方法使用sql server。如果是這樣,請嘗試在啓動dbcontext實例期間更改默認命令超時值,如下所述。您的數據庫操作可能需要比默認超時更長的時間。

public class YourContext : DbContext 
{ 
    public YourContext() 
     : base("YourConnectionStringName") 
    { 
     ((IObjectContextAdapter)this).ObjectContext.CommandTimeout = 300; 
    } 
} 
+0

我不認爲這會有所幫助,因爲相同的查詢可能超時某些WCF請求,但不會爲其他人。 – empo 2014-10-16 14:08:05