超时时间已到,但是尚未从池中获取连接异常捕获及解决办法

12,513次阅读
没有评论

共计 2707 个字符,预计需要花费 7 分钟才能阅读完成。

在使用连接池进行数据库连接时,我们经常会遇到 ” 超时时间已到, 但是尚未从池中获取连接 ” 这个异常。虽然这个异常很难复现,但我们希望能够全局捕获该异常,并给出一个友好的提示。但问题是,我们不清楚这个异常属于哪种类型,有些人说它属于 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.

然而,即使在极端情况下,这种情况仍然会发生。现在,我们只是想拦截这个异常并给出一个友好的提示。一种解决办法是通过 Exception.Message 进行拦截。

下面是一个示例代码,展示了如何在全局捕获该异常并给出友好提示:

示例代码

public class Sg1ExceptionFilterAttribute : ExceptionFilterAttribute{public override void OnException(HttpActionExecutedContext actionExecutedContext)
    {if (actionExecutedContext.Exception is InvalidOperationException || actionExecutedContext.Exception is Sq1Exception)
        {actionExecutedContext.Response = actionExecutedContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, "请稍后重试");
        }        
        base.OnException(actionExecutedContext);
    }
}

通过继承 ExceptionFilterAttribute 类,我们可以自定义异常过滤器来捕获特定类型的异常。在上述代码中,我们判断异常是否属于 InvalidOperationException 或 Sq1Exception,如果是,则将响应设为一个带有 ” 请稍后重试 ” 消息的错误响应。最后,调用基类的 OnException 方法,以确保异常继续传播到其他可能的异常处理程序。

这种方式能够有效地捕获并处理该异常,同时给用户提供了一个友好的提示信息,让他们知道发生了连接池超时的情况,并建议稍后重试。

总结一下,对于 ” 超时时间已到, 但是尚未从池中获取连接 ” 这个异常,我们可以通过编写一个自定义的异常过滤器来全局捕获并处理该异常。这样能够提供更好的用户体验,并提示用户稍后重试。同时,我们也提供了一种通过拦截 Exception.Message 的解决办法。

解决思路

一、看所有 open 的连接是否都 close 了。

二、如果访问量很大,加上 Max Pool Size=512 这一句,当然这是要以损失系统性能为代价的!这样以后一定可以解决你的问题!

解决方案

解决方案一

我想原因可能是并发操作。DataReader 是独占连接的,就是说你的程序可能设计上有问题。比如说最大连接设 100,假设有 100 个人同时使用 DataReader 正在读取数据库内容,那么当第 101 人读取的时候,连接池中的连接已经没有了,就会出现上面的错误。DataReader 是独占连接 的,每个 DataReader 都要占用一个连接。当然这个情况是偶尔出现的,所以会很长时间出现一次,因为只有同时有超过连接池最大连接数量的并发操作才会发生。而且你加大并发数量只能暂时缓解问题,如果你加大到 200 个并发连接,如果有 201 人同时操作怎么办?你说了你使用 Connection 对象的 Close()方法,这是不行的,因为 Close()方法仅仅是关闭连接,但这个连接没有释放,还是被这个对象占用,要释放必须使用 Connection 的 Dispose()方法显式释放连接才可以,否则这个对象占用的连接只能等到垃圾收集的情 况下才能被释放。这种情况肯定会出现“超时时间已到”的错误。

解决方法

解决方案一

  1. 修改几个关键页面或访问比较频繁的数据库访问操作,使用 DataAdapter 和 DataSet 来获取数据库数据,不要使用 DataReader。

  2. 在访问数据库的页面上使用数据缓存,如果页面的数据不是经常更新(几分钟更新一次)的话,使用 Cache 对象可以不用访问数据库而使用缓存中的内容,那么可以大大减少连接数量。

  3. 修改代码,把使用 Connection 对象的地方都在 Close()后面加上 Dispose()调用。

  4. 建议对数据库操作进行大的修改,建立自己的数据库操作代理类,继承

System.IDisposable 接口,强迫释放资源,这样就不会出现连接数量不够的问题了。

解决方案二

WEB.config 里面: 在数据库连接加 Max Pool Size = 512;server=local;uid=;pwd=;database=2004;Max Pool Size = 512;”>一劳永逸。解决方案三

估计是连接 (Connection) 对象没有 Close。倒是不必 Dispose,而 DataReader 用完后应该关闭,但不关闭也没问题,只是不关闭的话此连接对象就一直不能用,只要你最终关闭了连接对象就不会出问题。连接对象在 Open 后的操作都放在 try 块中,后面跟一个 finally 块:conn.Close();文章来源地址 https://www.toymoban.com/diary/problem/646.html

到此这篇关于超时时间已到, 但是尚未从池中获取连接异常捕获及解决办法的文章就介绍到这了, 更多相关内容可以在右上角搜索或继续浏览下面的相关文章,希望大家以后多多支持 TOY 模板网!

原文地址:https://www.toymoban.com/diary/problem/646.html

如若转载,请注明出处:如若内容造成侵权 / 违法违规 / 事实不符,请联系站长进行投诉反馈,一经查实,立即删除!

    正文完
     0
    Yojack
    版权声明:本篇文章由 Yojack 于1970-01-01发表,共计2707字。
    转载说明:
    1 本网站名称:优杰开发笔记
    2 本站永久网址:https://yojack.cn
    3 本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长进行删除处理。
    4 本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
    5 本站所有内容均可转载及分享, 但请注明出处
    6 我们始终尊重原创作者的版权,所有文章在发布时,均尽可能注明出处与作者。
    7 站长邮箱:laylwenl@gmail.com
    评论(没有评论)