java.sql.SQLRecoverableException: 关闭的连接 解决办法

来源:互联网 发布:淘宝客服搞笑对话段子 编辑:程序博客网 时间:2024/06/04 19:58

程序如果长时间不进行数据库操作,那么数据源中的 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


1 0
原创粉丝点击