【问题标题】:Is it possible to gets sql connection leaks using LINQ?是否可以使用 LINQ 获取 sql 连接泄漏?
【发布时间】:2009-04-23 05:56:07
【问题描述】:

我相信在使用 LINQ 时不可能出现 sql 连接泄漏,但是 NumberOfReclaimedConnections 的 perfmon 跟踪显示一个很高的数字,并且在高负载时,我们有时会遇到诸如“超时已过期。在从池。这可能是因为所有池连接都在使用中并且已达到最大池大小。

我们不对数据上下文使用 Dispose,因为我们使用了延迟加载。几篇文章和博文告诉我,这应该不是问题。

有时我们仍然会遇到这些异常。但不可能每个 linq 查询都保持连接打开,那么我们会有更多的异常。

编辑

应用程序是 WCF 服务。

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

【问题讨论】:

    标签: .net linq-to-sql connection-pooling


    【解决方案1】:

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

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

    这方面的文档含糊不清,虽然在大多数情况下,您可以通过不处理 DataContext 的方式侥幸逃脱,但在某些情况下,从连接加载的数据会保持连接本身处于活动状态。确认您的案例发生这种情况的最简单方法是对其进行测试。

    【讨论】:

      【解决方案2】:

      经过一番搜索,我发现了这个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;
      }
      

      如果我在上下文中添加调用 dispose,它们就会消失。

      【讨论】:

      • 这只是编译器的魔法。 foreach 是用于实例化枚举器的语法糖果,调用 MoveNext 直到它返回 false,然后在枚举器上调用 Dispose。仅供参考。
      【解决方案3】:

      您的数据库中是否遇到任何死锁?快速查看活动监视器应该会给您一些指示。

      您如何管理 DataContext 生命周期 - 您编写了哪种应用程序(网站、Windows 客户端等)?

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

      WCF 服务。在这种情况下,我非常喜欢“每个请求一个上下文”方法。我鼓励您将数据操作包装在 using() 语句中,以便在完成后释放上下文。

      【讨论】:

      • 我们没有遇到死锁问题,至少目前我所知道的没有,我们正在监控它。应用程序是 WCF 服务,数据上下文的生存时间永远不会超过服务调用。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-24
      • 1970-01-01
      • 2014-08-02
      相关资源
      最近更新 更多