连接池错误

use*_*827 2 sql-server transaction connection-pooling timeout

我从我的 .net 应用程序中收到以下错误。

Source: xxx.Services.xxx.xxx.xxxx.xxxx.xxxxRequest
    ---
    System.Data.Entity.Core.EntityException: The underlying provider failed on Open. ---> System.InvalidOperationException: Timeout expired.  The timeout period elapsed prior to obtaining a connection from the pool.  This may have occurred because all pooled connections were in use and max pool size was reached.
Run Code Online (Sandbox Code Playgroud)

我看过几篇关于这个连接池错误的帖子。我已经阅读了其中的大部分内容,我明白为什么会发生这种情况,以及应用程序端的可能解决方案,比如关闭应用程序打开的连接。这些是我的理解:

  1. 打开的连接并没有关闭,称为连接泄漏。
  2. 正在使用 100 多个并发连接。如果我们有 100 个以上的并发用户,请增加连接字符串中的最大池大小。
  3. 缓慢的查询或打开的事务会阻止新连接。当连接被慢速查询执行/打开事务保持打开时,而不是重用连接,新连接将打开并最终达到连接池最大值。

我如何从数据库端监控这一点。我看到了一些建议,例如使用 sp_who 或 sp_who2 查看现有会话。当我看到这些错误时执行 sp_who2 时,我看到很多活动会话,但是我怎么能看到连接池池下的信息和连接。问题:

  1. 有什么方法可以跟踪打开的连接并将其与从数据库端创建的连接池相关联。

我注意到当问题发生时,通常运行得更快的查询会变慢。

  1. 这是预期的吗?因为我怀疑慢查询是否导致连接池错误。

Dav*_*oft 7

有什么方法可以跟踪打开的连接并将其与从数据库端创建的连接池相关联。

在您的配置中设置应用程序名称,您可以在sys.dm_exec_sessions. 您将为每个连接字符串获得一个单独的连接池,因此如果您在连接字符串中设置应用程序名称,您就可以知道每个连接属于哪个池。

通常运行得更快的查询变慢了。是预期的吗?

是的。在您开始看到获取连接超时之前,您将等待最多 30 秒等待池连接变为可用。所以这可能是打开或重新打开连接的延迟,而不是缓慢的查询。

或者它可能是间接相关。通常,泄漏连接的代码路径仅在您遇到其他一些异常时才会发生。例如,数据库上的阻塞或资源耗尽导致超时异常,由于不使用using块导致连接泄漏。但这只是猜测。

BTW 99.99% 的原因是:“打开的连接没有关闭,称为连接泄漏。”