使用Spring JDBC时遇到的Software caused connection abort: recv failed问题

在使用Spring jdbc连接数据库时遇到一个头疼的问题:程序启动以后,如果长时间不访问调用,当再次调用时会报错: 
引用

org.springframework.dao.DataAccessResourceFailureException: ConnectionCallback; SQL []; IO 错误: Software caused connection abort: recv failed; nested exception is java.sql.SQLRecoverableException: IO 错误: Software caused connection abort: recv failed 
at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:253)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:349) 
at services.dao.DBUtil.subRptInfo(DBUtil.java:208) 
at services.impl.ServiceImpl.subRptInfo(ServiceImpl.java:170) 
at sun.reflect.GeneratedMethodAccessor65.invoke(Unknown Source) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
at java.lang.reflect.Method.invoke(Method.java:597) 
Caused by: java.sql.SQLRecoverableException: IO 错误: Software caused connection abort: recv failed 
at oracle.jdbc.driver.T4CCallableStatement.executeForRows(T4CCallableStatement.java:1062) 
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1329) 
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3584) 
at oracle.jdbc.driver.OraclePreparedStatement.execute(OraclePreparedStatement.java:3685) 
at oracle.jdbc.driver.OracleCallableStatement.execute(OracleCallableStatement.java:4714) 
at oracle.jdbc.driver.OraclePreparedStatementWrapper.execute(OraclePreparedStatementWrapper.java:1376)
at org.apache.commons.dbcp.DelegatingCallableStatement.execute(DelegatingCallableStatement.java:221) 
at services.dao.DBUtil$2.doInConnection(DBUtil.java:260) 
at services.dao.DBUtil$2.doInConnection(DBUtil.java:1) 
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:342) 
... 39 more 
Caused by: java.net.SocketException: Software caused connection abort: recv failed 
at java.net.SocketInputStream.socketRead0(Native Method) 
at java.net.SocketInputStream.read(SocketInputStream.java:147) 
at oracle.net.ns.Packet.receive(Packet.java:300) 
at oracle.net.ns.DataPacket.receive(DataPacket.java:106) 
at oracle.net.ns.NetInputStream.getNextPacket(NetInputStream.java:315) 
at oracle.net.ns.NetInputStream.read(NetInputStream.java:260) 
at oracle.net.ns.NetInputStream.read(NetInputStream.java:185) 
at oracle.net.ns.NetInputStream.read(NetInputStream.java:102) 
at oracle.jdbc.driver.T4CSocketInputStreamWrapper.readNextPacket(T4CSocketInputStreamWrapper.java:124)
at oracle.jdbc.driver.T4CSocketInputStreamWrapper.read(T4CSocketInputStreamWrapper.java:80) 
at oracle.jdbc.driver.T4CMAREngine.unmarshalUB1(T4CMAREngine.java:1137) 
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:290) 
at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:192) 
at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:531) 
at oracle.jdbc.driver.T4CCallableStatement.doOall8(T4CCallableStatement.java:204) 
at oracle.jdbc.driver.T4CCallableStatement.executeForRows(T4CCallableStatement.java:1041) 
... 48 more 


到处寻找资料后,发现是由于当数据库连接池中的连接被创建而长时间不使用的情况下,该连接会自动回收并失效,但客户端并不知道,在进行数据库操作时仍然使用的是无效的数据库连接造成的。解决方法是,在jdbc配置中加上: 
Xml代码   收藏代码
  1. <property name="validationQuery">  
  2.     <value>select * from dualvalue>  
  3. property>  

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

你可能感兴趣的:(项目经验)