sqlSession关闭,但数据库连接未关闭,该如何解决

时间:2021-10-13 23:42:53
配置文件如下:
    <context:annotation-config />
    <aop:aspectj-autoproxy proxy-target-class="true"/>
    <context:component-scan base-package="com.oa">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
    </context:component-scan>

    <!-- 给web使用的spring文件 -->
    <bean id="propertyConfigurer"
          class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:dbconfig.properties</value>
            </list>
        </property>
    </bean>
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
          init-method="init" destroy-method="close">
        <property name="url"
                  value="${url}"/>
        <property name="username" value="${username}"/>
        <property name="password" value="${password}"/>
        <property name="driverClassName" value="${driverClassName}"/>
        <property name="filters" value="${filters}"/>
        <property name="maxActive" value="${maxActive}"/>
        <property name="initialSize" value="${initialSize}"/>
        <property name="maxWait" value="${maxWait}"/>
        <property name="minIdle" value="${minIdle}"/>
        <property name="timeBetweenEvictionRunsMillis" value="${timeBetweenEvictionRunsMillis}"/>
        <property name="minEvictableIdleTimeMillis" value="${minEvictableIdleTimeMillis}"/>
        <property name="validationQuery" value="${validationQuery}"/>
        <property name="testWhileIdle" value="${testWhileIdle}"/>
        <property name="testOnBorrow" value="${testOnBorrow}"/>
        <property name="testOnReturn" value="${testOnReturn}"/>
        <property name="maxOpenPreparedStatements" value="${maxOpenPreparedStatements}"/>
        <property name="removeAbandoned" value="${removeAbandoned}"/>
        <!-- 打开removeAbandoned功能 -->
        <property name="removeAbandonedTimeout" value="${removeAbandonedTimeout}"/>
        <!-- 1800秒,也就是30分钟 -->
        <property name="logAbandoned" value="${logAbandoned}"/>
        <!-- 关闭abanded连接时输出错误日志 -->
        <property name="defaultAutoCommit" value="${autoCommit}"></property>
    </bean>

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="configLocation">
            <value>classpath:mybatisConfig.xml</value>
        </property>
        <property name="mapperLocations" value="classpath*:mappers/*.xml"/>
        <property name="dataSource">
            <ref bean="dataSource" />
        </property>
    </bean>
    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg index="0" ref="sqlSessionFactory" />
        <constructor-arg index="1" value="BATCH"></constructor-arg>
    </bean>
    <bean id="userDao" class="com.oa.dao.impl.SysUserBaseDaoImpl">
    </bean>
    <bean id="userServiceImpl" class="com.oa.service.impl.SysUserBaseService">
    </bean>
    <!-- 事务管理器 -->
    <bean id="txManager"
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <!-- 开启事务支持 -->
    <tx:annotation-driven transaction-manager="txManager"/>


代码调用如下:
    @Override
    public List<SysUserBase> select(HashMap<String, Object> map) {

        List<SysUserBase> lst=sqlSession.selectList("com.oa.mapper.ext.SysUserBaseMapper.selectByMap",map);
        log.info("查询结果"+ JSONObject.toJSONString(lst));
        return lst;
    }


输出的日志如:
2014-10-28 22:40:23 DEBUG: Committing JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@4e453182]
2014-10-28 22:40:23 DEBUG: Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@591e356b]
2014-10-28 22:40:23 DEBUG: Returning JDBC Connection to DataSource
2014-10-28 22:40:23 INFO : 查询结果


显示sqlSession已关闭,但是数据库里的连接每次都增加一个。

杀死 1997 root localhost:53562 oadb Sleep 32 --- ---
杀死 1998 root localhost:53571 oadb Sleep 28 --- ---
杀死 2003 root localhost:53575 oadb Sleep 19 --- ---
杀死 2004 root localhost:53576 oadb Sleep 18 --- ---
杀死 2007 root localhost:53583 oadb Sleep 8 --- ---
杀死 2008 root localhost:53585 oadb Sleep 7 --- ---
杀死 2009 root localhost:53587 oadb Sleep 7 --- ---
杀死 2010 root localhost:53589 oadb Sleep 7 --- ---
杀死 2011 root localhost:53591 oadb Sleep 7 --- ---
杀死 2012 root localhost:53592 oadb Sleep 6 --- ---
杀死 2013 root localhost:53594 oadb Sleep 6 --- ---
杀死 2014 root localhost:53596 oadb Sleep 6 --- ---
杀死 2015 root localhost:53597 oadb Sleep 5 --- ---
杀死 2016 root localhost:53599 oadb Sleep 5 --- ---
杀死 2017 root localhost:53601 oadb Sleep 5 --- ---
杀死 2018 root localhost:53602 oadb Sleep 4 --- ---
杀死 2019 root localhost:53604 oadb Sleep 4 --- ---
杀死 2020 root localhost:53606 oadb Sleep 4 --- ---

这个总是该怎么解决,请各位高手帮忙解答一下。

5 个解决方案

#1


    同样的配置,我在WEB里请求就会出现上面这种情况,如果在一个main方法里做测试,数据库连接使用完成后就会自动关闭。

#2


看配置用的是DBCP连接池,DBCP我用的是commons-dbcp没有出过问题,没有用过alibaba的。
这是我用的
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.4</version>
        </dependency>

#3


这个是需要理解WEB程序的生命周期的,WEB程序里每次请求结束并不意味着程序停止运行。也就是说DataSource的线程池没有关闭 - - 所以DataSource管理的Connection为关闭。
而你通过main方法虚拟的运行环境(没有特殊设置的话)在main方法结束后会停止DataSource用于维护Connection的线程池,所以DataSource会在线程终止时关闭自己维护的Connection。
你可以在main方法的sqlConnection关闭后Thread.sleep(5000)试试,看看这这期间Connection并没有关闭,而是退出main方法后关闭的。

#4


  犯了一个入门的问题。每次请求都初始化一个上下文用来创建需要的对象。

已修改为注入的方式。

#5


楼主,我遇到了同样的问题,借问一下,问题解决了没?怎么解决的? sqlSession关闭,但数据库连接未关闭,该如何解决

#1


    同样的配置,我在WEB里请求就会出现上面这种情况,如果在一个main方法里做测试,数据库连接使用完成后就会自动关闭。

#2


看配置用的是DBCP连接池,DBCP我用的是commons-dbcp没有出过问题,没有用过alibaba的。
这是我用的
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.4</version>
        </dependency>

#3


这个是需要理解WEB程序的生命周期的,WEB程序里每次请求结束并不意味着程序停止运行。也就是说DataSource的线程池没有关闭 - - 所以DataSource管理的Connection为关闭。
而你通过main方法虚拟的运行环境(没有特殊设置的话)在main方法结束后会停止DataSource用于维护Connection的线程池,所以DataSource会在线程终止时关闭自己维护的Connection。
你可以在main方法的sqlConnection关闭后Thread.sleep(5000)试试,看看这这期间Connection并没有关闭,而是退出main方法后关闭的。

#4


  犯了一个入门的问题。每次请求都初始化一个上下文用来创建需要的对象。

已修改为注入的方式。

#5


楼主,我遇到了同样的问题,借问一下,问题解决了没?怎么解决的? sqlSession关闭,但数据库连接未关闭,该如何解决