java.sql.SQLRecoverableException: 關閉的連接

目錄

 

 一.問題

二.問題總結:

三.Spring+IBatis解決方式

五.c3p0解決的辦法是: 

注意:

擴展:

DBCP連接池:

參考:


 一.問題

  • 程序如果長時間不進行數據庫操作,那麼數據源中的 Connection 很可能已經斷開。其原因有可能是防火牆,或者連接的數據庫設置的超時時間。

二.問題總結:

  • 當數據庫連接池中的連接被創建而長時間不使用的情況下,該連接會自動回收並失效,但客戶端並不知道,在進行數據庫操作時仍然使用的是無效的數據庫連接,這樣,就導致客戶端程序報“ java.sql.SQLException: Io 異常: Connection reset” 或“java.sql.SQLException 關閉的連接”異常。

三.Spring+IBatis解決方式

  • 在配置數據源後面加上
<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"/>
        <property name="validationQuery" value="select * 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> 的子元素,否則不起作用。

擴展:

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> 


 

參考:

https://blog.csdn.net/zqd_java/article/details/53738373

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章