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
初步解决方案
查看了上述的资料,尝试了将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>
DBCP连接Oracle,按照如下步骤操作:
- 启动web应用程序
- 尝试查询,成功
- 关闭数据库,然后启动数据库,中间不作页面查询
- 测试查询,报如下异常
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: 无法从套接字读取更多的数据
将配置加上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>
没找到关于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;
BasicDataSource.java
// Can't test without a validationQuery if (validationQuery == null) { setTestOnBorrow(false); setTestOnReturn(false); setTestWhileIdle(false); }
作者:Nick Huang 博客:http://www.cnblogs.com/nick-huang/
本博客为学习、笔记之用,以笔记形式记录学习的知识与感悟。学习过程中可能参考各种资料,如觉文中表述过分引用,请务必告知,以便迅速处理。如有错漏,不吝赐教。
如果本文对您有用,点赞或评论哦;如果您喜欢我的文章,请点击关注我哦~
本博客为学习、笔记之用,以笔记形式记录学习的知识与感悟。学习过程中可能参考各种资料,如觉文中表述过分引用,请务必告知,以便迅速处理。如有错漏,不吝赐教。
如果本文对您有用,点赞或评论哦;如果您喜欢我的文章,请点击关注我哦~