java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > java.sql.SQLException 关闭的连接

java.sql.SQLRecoverableException关闭的连接异常问题及解决办法

作者:前端蜗牛君

当数据库连接池中的连接被创建而长时间不使用的情况下,该连接会自动回收并失效,就导致客户端程序报“ java.sql.SQLException: Io 异常: Connection reset” 或“java.sql.SQLException 关闭的连接”异常问题,下面给大家分享解决方案,一起看看吧

程序如果长时间不进行数据库操作,那么数据源中的 Connection 很可能已经断开。其原因有可能是防火墙,或者连接的数据库设置的超时时间。

问题总结:

当数据库连接池中的连接被创建而长时间不使用的情况下,该连接会自动回收并失效,但客户端并不知道,在进行数据库操作时仍然使用的是无效的数据库连接,这样,就导致客户端程序报“ java.sql.SQLException: Io 异常: Connection reset” 或“java.sql.SQLException 关闭的连接”异常。

在配置数据源后面加上

<property name="validationQuery" value="select * from dual"/>

配置后,客户端在使用一个无效的连接时会先对该连接进行测试,如果发现该连接已经无效,则重新从连接池获取有效数据库连接来使用

程序中采用的是Spring+IBatis,数据源配置如下:在 applicationContext.xml中如下设置:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
  <property name="driverClassName" value="${driver}"/>
  <property name="url" value="${url}"/>
  <property name="username" value="${username}"/>
  <property name="password" value="${password}"/>
  <property name="maxActive" value="100"/>
        <property name="maxIdle" value="30"/>
        <property name="maxWait" value="1000"/>
        <property name="defaultAutoCommit" value="true"/>
 </bean>

 经过查找资料和分析,得出该问题主要是由于连接时间过长,失效所致,将以上配置修改如下:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
  <property name="driverClassName" value="${driver}"/>
  <property name="url" value="${url}"/>
  <property name="username" value="${username}"/>
  <property name="password" value="${password}"/>
  <property name="maxActive" value="100"/>
        <property name="maxIdle" value="30"/>
        <property name="maxWait" value="1000"/>
        <property name="defaultAutoCommit" value="true"/>
        <span style="background-color: rgb(255, 0, 0);"><property name="validationQuery" value="select * from dual"/></span>
 </bean>

顺便提一下数据库DBCP连接池:

在applicationContext.xml中:

<!-- 数据源1 -->  
    <bean id="dataSource"  
          class="org.apache.commons.dbcp.BasicDataSource"  
          destroy-method="close">  
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>  
        <property name="url" value="jdbc:mysql://192.168.0.109:3306/test?useUnicode=true&characterEncoding=UTF-8"/>  
        <property name="username" value="root"/>  
        <property name="password" value="root"/>  
        <!--maxActive: 最大连接数量-->    
        <property name="maxActive" value="150"/>  
        <!--minIdle: 最小空闲连接-->    
        <property name="minIdle" value="5"/>  
        <!--maxIdle: 最大空闲连接-->    
        <property name="maxIdle" value="20"/>  
        <!--initialSize: 初始化连接-->    
        <property name="initialSize" value="30"/>  
        <!-- 连接被泄露时是否打印 -->  
        <property name="logAbandoned" value="true"/>  
        <!--removeAbandoned: 是否自动回收超时连接-->    
        <property name="removeAbandoned"  value="true"/>  
        <!--removeAbandonedTimeout: 超时时间(以秒数为单位)-->    
        <property name="removeAbandonedTimeout" value="10"/>  
        <!--maxWait: 超时等待时间以毫秒为单位 1000等于60秒-->  
        <property name="maxWait" value="1000"/>  
        <!-- 在空闲连接回收器线程运行期间休眠的时间值,以毫秒为单位. -->  
        <property name="timeBetweenEvictionRunsMillis" value="10000"/>  
        <!--  在每次空闲连接回收器线程(如果有)运行时检查的连接数量 -->  
        <property name="numTestsPerEvictionRun" value="10"/>  
        <!-- 1000 * 60 * 30  连接在池中保持空闲而不被空闲连接回收器线程-->  
        <property name="minEvictableIdleTimeMillis" value="10000"/>  
    <property name="validationQuery" value="SELECT NOW() FROM DUAL"/>  
    </bean>  

c3p0解决:

解决的办法是: 

在 applicationContext.xml中如下设置:

<!-- 数据库连接声明 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="com.alibaba.china.jdbc.SimpleDriver" />
<!-- <property name="driverClass" value="oracle.jdbc.OracleDriver" /> -->
<property name="jdbcUrl" value="jdbc:oracle:thin:@202.116.70.180:61166:orcl" />
<!-- 每60秒检查所有连接池中的空闲连接。Default: 0 -->
<property name="idleConnectionTestPeriod" value="60" />
 <!--如果设为true那么在取得连接的同时将校验连接的有效性。Default: false -->
<property name="testConnectionOnCheckin" value="true" />
<!--c3p0将建一张名为Test的空表,并使用其自带的查询语句进行测试。如果定义了这个参数那么 属性preferredTestQuery将被忽略。你不能在这张Test表上进行任何操作,它将只供c3p0测试使用。Default: null -->
<property name="automaticTestTable" value="Test" />
<property name="properties">
<props>
<prop key="clientEncoding">GBK</prop>
<prop key="serverEncoding">CP1252</prop>
<prop key="user">WDS</prop>
<prop key="password">HelloOracle</prop> 
</props>
</property>
</bean>

配置项一定要作为 <bean> 的子元素,而不能做为 <properties> 的子元素,否则不起作用。

参考:

http://my.oschina.net/tianzimensheng/blog/65225

http://www.cnblogs.com/younes/archive/2012/06/01/2529483.html

http://www.cnblogs.com/safeking/archive/2007/02/01/637067.html

到此这篇关于java.sql.SQLRecoverableException关闭的连接异常问题及解决办法的文章就介绍到这了,更多相关java.sql.SQLException 关闭的连接内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文