zoukankan      html  css  js  c++  java
  • 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强行回收了!

  • 相关阅读:
    LintCode "Maximum Gap"
    LintCode "Wood Cut"
    LintCode "Expression Evaluation"
    LintCode "Find Peak Element II"
    LintCode "Remove Node in Binary Search Tree"
    LintCode "Delete Digits"
    LintCode "Binary Representation"
    LeetCode "Game of Life"
    LintCode "Coins in a Line"
    LintCode "Word Break"
  • 原文地址:https://www.cnblogs.com/flgb/p/12885146.html
Copyright © 2011-2022 走看看