2011-10-20 233 views
44

我们使用Oracle作为Web应用程序的数据库。应用程序大部分时间运行良好,但是我们得到这个“没有更多数据从套接字读取”的错误。没有更多数据从套接字错误中读取

Caused by: java.sql.SQLRecoverableException: No more data to read from socket 
    at oracle.jdbc.driver.T4CMAREngine.unmarshalUB1(T4CMAREngine.java:1142) 
    at oracle.jdbc.driver.T4CMAREngine.unmarshalSB1(T4CMAREngine.java:1099) 
    at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:288) 
    at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:191) 
    at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:523) 
    at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:207) 
    at oracle.jdbc.driver.T4CPreparedStatement.executeForDescribe(T4CPreparedStatement.java:863) 
    at oracle.jdbc.driver.OracleStatement.executeMaybeDescribe(OracleStatement.java:1153) 
    at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1275) 
    at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3576) 
    at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:3620) 
    at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeQuery(OraclePreparedStatementWrapper.java:1491) 
    at org.apache.commons.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:93) 
    at org.apache.commons.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:93) 
    at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:208) 
    at org.hibernate.loader.Loader.getResultSet(Loader.java:1869) 
    at org.hibernate.loader.Loader.doQuery(Loader.java:718) 
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:270) 
    at org.hibernate.loader.Loader.doList(Loader.java:2449) 
    ... 63 more 

我们使用spring,hibernate,并在我的applciation上下文文件中使用了以下数据源。

<bean class="org.apache.commons.dbcp.BasicDataSource" 
     destroy-method="close" id="dataSource"> 
     <property name="driverClassName" value="${database.driverClassName}" /> 
     <property name="url" value="${database.url}" /> 
     <property name="username" value="${database.username}" /> 
     <property name="password" value="${database.password}" /> 
     <property name="defaultAutoCommit" value="false" /> 
     <property name="initialSize" value="10" /> 
     <property name="maxActive" value="30" /> 
     <property name="validationQuery" value="select 1 from dual" /> 
     <property name="testOnBorrow" value="true" /> 
     <property name="testOnReturn" value="true" /> 
     <property name="poolPreparedStatements" value="true" /> 
     <property name="removeAbandoned" value="true" /> 
     <property name="logAbandoned" value="true" /> 
    </bean> 

我不确定这是因为应用程序错误,数据库错误还是网络错误。

我们看到在Oracle日志

Thu Oct 20 10:29:44 2011 
Errors in file d:\oracle\diag\rdbms\ads\ads\trace\ads_ora_3836.trc (incident=31653): 
ORA-03137: TTC protocol internal error : [12333] [4] [195] [3] [] [] [] [] 
Incident details in: d:\oracle\diag\rdbms\ads\ads\incident\incdir_31653\ads_ora_3836_i31653.trc 
Thu Oct 20 10:29:45 2011 
Trace dumping is performing id=[cdmp_20111020102945] 
Thu Oct 20 10:29:49 2011 
Sweep [inc][31653]: completed 
Sweep [inc2][31653]: completed 
Thu Oct 20 10:34:20 2011 
Errors in file d:\oracle\diag\rdbms\ads\ads\trace\ads_ora_860.trc (incident=31645): 
ORA-03137: TTC protocol internal error : [12333] [4] [195] [3] [] [] [] [] 
Incident details in: d:\oracle\diag\rdbms\ads\ads\incident\incdir_31645\ads_ora_860_i31645.trc 
Thu Oct 20 10:34:21 2011 

Oracle版本如下:11.2.0.1.0

+3

看起来您的Oracle服务器在读取某种结果集时粗暴地断开了您的应用程序连接。 –

+2

此错误很可能发生在使用数据库连接池的应用程序中。当应用程序检出已超时或已被检测到的连接并将其用于连接到数据库时,会发生此错误。 – Ritesh

+0

@ User67546我已经设置了连接池配置以在使用前验证连接。不应该忽视陈旧的连接 – Kathir

回答

25

对于这样的,你应该包括Oracle支持的错误。不幸的是,你没有提到你使用的是什么Oracle版本。该错误可能与优化器绑定窥视有关。根据oracle版本的不同,可能会有不同的解决方法。

您有两种方法来解决这个问题:

  • 升级到11.2
  • 将Oracle设置参数_optim_peek_user_binds = false

当然下划线参数只能在由甲骨文支持

建议设置
+0

我已经更新了Oracle版本。 – Kathir

+0

已联系oracle,这是一个_optim_peek_user_binds问题,我们必须升级或修补它。 – Kathir

+5

我仍然在11.2.0.2.0 - 64位上得到这个错误,重启后oracle db - pool没有重新调用。 – Akvel

4

尝试两件事:

  1. 在oracle server server上的$ ORACLE_HOME/network/admin/tnsnames.ora中设置=专用于server = shared,一次允许多个连接。重新启动oracle。
  2. 如果您使用的是Java,这可能帮助您:在java/jdk1.6.0_31/jre/lib/security/Java.security变化securerandom.source=file:/dev/urandomsecurerandom.source=file:///dev/urandom
-3

我那么这个错误重新启动,我的客户端应用程序和数据库之间保持的连接池我的GlassFish服务器,并且错误去远。因此,如果适用,请尝试重新启动应用程序服务器

+5

是的,当您重新启动应用程序时问题消失,但这不是问题的重点,并且您无法在生产中始终重新启动。 – javagirl

+0

这实际上是一个完全合法的答案。当数据库重新启动时,有时后端/应用程序不能正确处理它。所以,是的,应用程序应该是固定的,但是当你需要应用程序回应时,这并不能帮助你。重新启动应用程序。 –

+0

@javagirl你指的是什么问题? OP实际上没有提及*任何问题。他没有问“我们应该如何重写应用程序?”而这个答案也不表示“这是一个长期的解决方案。”当数十人等待应用程序开始响应时,不要告诉他们“重写它”。 –

6

我们面临同样的问题,我们通过增加连接池的大小initialSizemaxActive来解决它。

您可以检查this link

也许这可以帮助别人。

3

将JRE从7降级到6为我解决了这个问题。

+1

只是一个想法,也许这是因为JDBC驱动程序版本而起作用:11.2.0.4支持JDK 6,7和8,但仅支持11.2.0.3 JDK 6 http://www.oracle.com/technetwork/apps-tech/jdbc -112010-090769.html – maxivis

1

我有同样的问题。在以下情况下,我能够从应用程序端解决问题:

JDK8,spring framework 4.2.4.RELEASE,apache tomcat 7.0.63,Oracle Database 11g企业版11.2.0.4。0

我使用的数据库连接池apache tomcat-jdbc

可以采取以下的配置参数作为参考:

<Resource name="jdbc/exampleDB" 
     auth="Container" 
     type="javax.sql.DataSource" 
     factory="org.apache.tomcat.jdbc.pool.DataSourceFactory" 
     testWhileIdle="true" 
     testOnBorrow="true" 
     testOnReturn="false" 
     validationQuery="SELECT 1 FROM DUAL" 
     validationInterval="30000" 
     timeBetweenEvictionRunsMillis="30000" 
     maxActive="100" 
     minIdle="10" 
     maxWait="10000" 
     initialSize="10" 
     removeAbandonedTimeout="60" 
     removeAbandoned="true" 
     logAbandoned="true" 
     minEvictableIdleTimeMillis="30000" 
     jmxEnabled="true" 
     jdbcInterceptors="org.apache.tomcat.jdbc.pool.interceptor.ConnectionState; 
     org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer" 
     username="your-username" 
     password="your-password" 
     driverClassName="oracle.jdbc.driver.OracleDriver" 
     url="jdbc:oracle:thin:@localhost:1521:xe"/> 

这种结构足以修复错误。这在上面提到的场景中适用于我。

有关安装的Apache Tomcat-JDBC的详细信息:https://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html

2

另一种情况:如果您要发送日期参数,参数化的SQL,请确保您发送java.sql.Timestamp而不是java.util.Date。否则,你得到

java.sql.SQLRecoverableException:没有更多的数据从套接字读取

实例声明: 在我们的Java代码中,我们使用org.apache.commons.dbutils,我们有以下几点:

final String sqlStatement = "select x from person where date_of_birth between ? and ?"; 
java.util.Date dtFrom = new Date(); //<-- this will fail 
java.util.Date dtTo = new Date(); //<-- this will fail 
Object[] params = new Object[]{ dtFrom , dtTo }; 
final List mapList = (List) query.query(conn, sqlStatement, new MapListHandler(),params); 

上述失败直到我们将日期参数更改为java.sql.Timestamp

java.sql.Timestamp tFrom = new java.sql.Timestamp (dtFrom.getTime()); //<-- this is OK 
java.sql.Timestamp tTo = new java.sql.Timestamp(dtTo.getTime()); //<-- this is OK 
Object[] params = new Object[]{ tFrom , tTo }; 
final List mapList = (List) query.query(conn, sqlStatement, new MapListHandler(),params); 
+0

我不知道为什么投票。这是合法的,它可以帮助某人 – chrisl08

0

是的,正如@ggkmath所说,有时一个很好的重新启动正是你所需要的。就像“联系作者并让他重写应用程序,同时等待”不是一种选择。

这种情况发生在应用程序未以可处理底层数据库重新启动的方式写入时。

相关问题