2009-04-23 92 views
6

我认为使用LINQ时无法获得sql连接泄漏,但是NumberOfReclaimedConnections的perfmon跟踪显示的数量很大,而且在高负载情况下,我们有时会收到“Timeout过期”这样的异常。这可能是因为所有池式连接都在使用中,并且达到了最大池大小“。是否有可能使用LINQ获取sql连接泄漏?

我们不会在datacontexts上使用Dispose,因为我们使用了加载。几篇文章和blogpost告诉我这不应该是一个问题。

我们仍然有时会得到这些例外。但是,并不是每一个linq查询都会保持连接的开放,那么我们就会有更多的异常。

编辑

应用程序是一个WCF服务。

如果你看看Linq和大多数文章的文档,他们声称Dispose不是释放连接所必需的。他们声称DataCOntext仅在需要它的短时间内保持连接打开。

回答

8

当您的DataContext未被处置并保持活动状态时,关联的连接也将保持活动状态。数据库连接是非托管资源,所有非托管资源必须正确处置。

即使使用延迟加载并且没有明确定义的范围,您仍然应该在逻辑工作单元结束时清理数据库连接。在ASP.NET应用程序中,最新的可能时刻是在请求处理结束时 - 在Globals.asax文件的Application_EndRequest方法中。在WCF服务中,任何活动的数据上下文都应该在每个服务方法调用结束时处理掉。

此文档很模糊,大多数情况下,您可以避免不配置DataContext,但似乎存在一些从连接加载的数据保持连接本身存活的情况。确认发生这种情况的最简单方法就是测试它。

+0

不错的加法。谢谢:) – 2009-04-23 06:33:37

0

你是否在数据库中发生死锁?快速查看活动监视器应该给你一些指示。

你如何管理DataContext生命周期 - 你编写了什么样的应用程序(一个网站,一个Windows客户端,其他)?

一旦在查询或操作中使用,DataContext将保持连接,以便加载的实体可以延迟加载&等,因此您必须规划在应用程序中如何使用DataContext。

WCF服务..在这种情况下,我是“每个请求一个上下文”方法的忠实粉丝。我鼓励你将你的数据操作包装在using()语句中,以便在完成时处理上下文。

+0

我们对死锁没有任何问题,至少现在我不知道,我们正在监控它。 应用程序是WCF服务,并且数据上下文应该永远不会超过服务调用。 – Atle 2009-04-23 06:20:28

4

我发现经过一番搜索,我发现这个question and answer,它说,LINQ可以被愚弄留下打开的连接..

我做的,也再现这个小测试代码。如果我用foreach替换了Enumerator,它可以正常工作,但Enumerator保持连接处于打开状态。

public Organisation RunTestQuery2() 
{ 
    IEnumerable<Organisation> orgs = base.GetEntities<Organisation>().Take(5); 

    var enumerator = orgs.GetEnumerator(); 
    int i = 0; 


    while (enumerator.MoveNext()) 
    { 
     var org = enumerator.Current; 
     Debug.WriteLine(org.DescribingName); 
     if (i == 3) 
     { 
      return org; 
     } 
     i++; 
    } 

    return null; 
} 

如果我添加一个调用来处理上下文,它们消失。

+0

这只是编译器的魔力。 foreach是用于实例化枚举器的语法糖果,调用MoveNext直到它返回false,然后在枚举器上调用Dispose。只是FYI。 – Kilanash 2011-07-06 20:36:29