• 6. Connection has already been closed 数据库连接被关闭


    生产上Tomcat出现 Connection has already been closed.问题,但是在uat测试是好的!

    遇见两次:

    1.某个程序dao中执行逻辑异常复杂,有时候需要执行一分多钟,uat正常执行,生产上个别执行时间长的会出现Connection has already been closed!

    2.某程序在service中注入dao,业务逻辑中获取一批数据放在list中遍历,每遍历一次用dao直接调用方法,大概四五个dao的方法,过一会出现Connection has already been closed!

    问题根本原因:

    1.小伙伴配置时,会添加以下连接配置参数

    removeAbandoned="true"

    removeAbandonedTimeout="60"(removeAbandonedTimeout”(默认300秒)
    logAbandoned="true"

     有时候代码中会有从连接池中获取连接使用后忘记了连接的关闭,这样连池的连接就会逐渐达到maxActive直至连接池无法getConnection。

    连接池一般提供检查功能,即设置了removeAbandoned="true",连接就可以自动回收。

    连接自动回收判断标准:

    <!--是否回收已经超过 removeAbandonedTimeout 设置的无效连接,自动回收超时连接
              启动机制:getNumActive() > getMaxActive() - 3 和 getNumIdle() < 2 
              假设maxActive=20,而当前18个活动连接,1个空闲连接,机制将会启动
              但是只有在活动连接没有使用的时长超过“removeAbandonedTimeout”(默认300秒)上述配置为60s,的连接将被回收-->

    配置logAbandoned="true",会在回收连接时打印日志。removeAbandoned是连接池的高级功能,生产环境上应当慎重配置。

    因为有时应用程序执行长事务,在这种情况下,极有可能连接会被连接池误回收。

    该配置一般在uat使用,为了定位连接泄漏的位置而去使用。生产环境中连接的关闭应该靠程序自己保证。

    问题一产生原因:如上述所说,直接对号入座

     解决:1.适当增大 removeAbandonedTimeout时间,让单次获取的连接能够执行时间更长一点,让其支持更长一点的事务。

    问题二产生原因:需要拐个弯,因为spring中配置事务时配置的service开启一个事务,在service中拿到连接开启一个事务,而遍历中一直使用注入的dao去调用方法,

            其本质就是一直使用一个连接,不会遍历一次执行完重新获取连接,导致该连接超时被tomcat关闭回收。

    解决2:将所有dao层方法抽出来另放一个业务service层,注入dao层,方法里使用dao的调用方法。在原来的service层中注入业务service,原有dao调用的方法,全部替换成业务service调用的方法。

        这样每次业务service调用到(update、insert、delete)方法,就开启一个事务,执行完就回收。再执行就有获取一个连接,执行到事务方法后,又会主动关闭,

        就不会因连接超时被tomcat强行回收了!

  • 相关阅读:
    EonerCMS——做一个仿桌面系统的CMS(五)
    给博客园的忠告——做事态度决定用户忠诚度
    EonerCMS——做一个仿桌面系统的CMS(三)
    EonerCMS——做一个仿桌面系统的CMS(七)
    更改windows服务的配置文件(app.config)必须重启服务才能生效吗?
    jQuery:动态改变html表单的目标页(Target)
    iBatis.Net实现返回DataTable和DataSet对象
    更上层楼:动态安装你的windows服务
    MongoDB简单实践:Only CRUD
    发布一个从webform改进而来的asp.net mvc分页工具类
  • 原文地址:https://www.cnblogs.com/flgb/p/12885146.html
Copyright © 2020-2023  润新知