DBCP連接Oracle,數據庫重啟后現OALL8 is in an inconsistent state異常


最近,DBCP連接Oracle,數據庫重啟后現OALL8 is in an inconsistent state異常。

 

版本說明

  • commons-dbcp-1.4.jar
  • commons-pool-1.5.4.jar

 

關鍵字

異常關鍵字為:

  • 無法從套接字讀取更多的數據
  • OALL8 處於不一致狀態
  • Io 異常: 斷開的管道

 

參考的鏈接

java.sql.SQLException: OALL8 is in an inconsistent state

OALL8 is in an inconsistent state

dbcp基本配置和重連配置

 

初步解決方案

查看了上述的資料,嘗試了將10.2.0.3的驅動降為9.2.0.0的,結果無效。由此看來,此問題的原因有很多種,看來我並不是帖子上遇到的那些原因。

后來,在數據源的配置上加上連接池的心跳檢測就ok了(見如下代碼除驅動類、賬號、密碼外的配置)。

配置項意義見:BasicDataSource Configuration Parameters

 

<!-- 配置數據源 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="${jdbc.driverClassName}" />
    <property name="url" value="${jdbc.url}" />
    <property name="username" value="${jdbc.username}" />
    <property name="password" value="${jdbc.password}" />
    
    <!-- 打開用異步線程進行檢查連接 -->
    <property name="testWhileIdle"><value>true</value></property>
    <property name="testOnBorrow"><value>false</value></property>  
    <property name="testOnReturn"><value>false</value></property>  
    <property name="validationQuery"><value>select 1 from dual</value></property>  
    <property name="validationQueryTimeout"><value>1</value></property>  
    <property name="timeBetweenEvictionRunsMillis"><value>30000</value></property>  
    <property name="numTestsPerEvictionRun"><value>20</value></property> <!-- 每次檢查連接的數量,建議設置和maxActive一樣大,這樣每次可以有效檢查所有的連接 -->
</bean>

 

問題在於連接池中的連接經過數據庫重啟后實際上已失效(或過時),而連接池並不知道,繼續正常使用,導致報錯。如今加上檢查連接測試即正常。

 

為什么加了檢查連接就可以了呢

因在公司時間較緊迫,匆匆解決后,有些問題仍不清晰。

回家后,對問題做了重現,現簡要記錄一下。

 

之前的配置如下,只有數據庫的連接,連validationQuery都沒有配,所以dbcp並不作任何連接的檢查:

<!-- DBCP -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
    <property name="url"
        value="jdbc:oracle:thin:@10.0.0.109:1521:orcl" />
    <property name="username" value="scott" />
    <property name="password" value="xxxxx" />
</bean>
View Code

 

 

DBCP連接Oracle,按照如下步驟操作:

  1. 啟動web應用程序
  2. 嘗試查詢,成功
  3. 關閉數據庫,然后啟動數據庫,中間不作頁面查詢
  4. 測試查詢,報如下異常
org.springframework.dao.RecoverableDataAccessException: <|### Error querying database.  
Cause: java.sql.SQLRecoverableException: 無法從套接字讀取更多的數據<|### The error may exist in file [D:\workspace\jee_workspace\mybatis3spring3Intg\target\classes\com\nicchagil\mybatis3spring3intg\mapper\sqlxml\user_mapper.xml]
<|### The error may involve defaultParameterMap<|### The error occurred while setting parameters
<|### SQL: select        u.id, u.username, u.password, u.childhoodname, u.age        from t_user u     where 1 = 1
<|### Cause: java.sql.SQLRecoverableException: 無法從套接字讀取更多的數據|; SQL []; 
無法從套接字讀取更多的數據; nested exception is java.sql.SQLRecoverableException: 無法從套接字讀取更多的數據
View Code

 

 

將配置加上validationQuery后即無問題,因連接池中借出連接時會用此配置項的SQL檢查連接是否有效。(默認testOnBorrow為true)

Oracle的配置為如下:

<!-- DBCP -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
    <property name="url"
        value="jdbc:oracle:thin:@10.0.0.109:1521:orcl" />
    <property name="username" value="scott" />
    <property name="password" value="xxxxx" />
    <property name="validationQuery"><value>select 1 from dual</value></property>
</bean>
View Code

 

沒找到關於BDCP1.4的配置項說明文檔(知道在哪的童靴請告知),翻了源碼確定這些信息(初步確認,並不完全確認,請知悉),附:

BasicDataSource.java

/**
 * The indication of whether objects will be validated before being
 * borrowed from the pool.  If the object fails to validate, it will be
 * dropped from the pool, and we will attempt to borrow another.
 */
protected boolean testOnBorrow = true;
View Code

 

BasicDataSource.java

// Can't test without a validationQuery
if (validationQuery == null) {
    setTestOnBorrow(false);
    setTestOnReturn(false);
    setTestWhileIdle(false);
}
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM