无法从套接字读取更多数据错误

问题描述 投票:0回答:13

我们使用 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,我的应用程序上下文文件中有以下数据源。

<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

oracle hibernate spring jdbc
13个回答
36
投票

对于此类错误,您应该联系 Oracle 支持。不幸的是,您没有提及您正在使用什么 Oracle 版本。该错误可能与优化器绑定查看有关。根据 Oracle 版本的不同,适用不同的解决方法。

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

  • 升级到11.2
  • 设置预言机参数
    _optim_peek_user_binds = false

当然,只有在 Oracle 支持人员建议的情况下才应设置下划线参数


15
投票

这是一个非常低级的异常,即ORA-17410。

发生这种情况可能有多种原因:

  1. 网络暂时出现问题。

  2. JDBC 驱动程序版本错误。

  3. 特殊数据结构(数据库端)的一些问题。

  4. 数据库错误。

就我而言,这是我们在数据库上遇到的错误,需要修补。

如果这是网络问题并且您正在使用数据源(池),则重新启动该工作可能会作为解决方法。


10
投票

我们面临同样的问题,我们通过增加连接池的

initialSize
maxActive
大小来解决它。

您可以查看此链接

也许这对某人有帮助。


9
投票

另一种情况:如果您要将日期参数发送到参数化 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); 

5
投票

尝试两件事:

  1. 在 oracle 服务器上的 $ORACLE_HOME/network/admin/tnsnames.ora 中设置 server=dedicated 到 server=shared 以允许一次多个连接。重启oracle。
  2. 如果您使用 Java,这可能对您有帮助:在
    java/jdk1.6.0_31/jre/lib/security/Java.security
    中将
    securerandom.source=file:/dev/urandom
    更改为
    securerandom.source=file:///dev/urandom

4
投票

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

JDK8、spring框架4.2.4.RELEASE、apache tomcat 7.0.63、Oracle数据库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


3
投票

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


1
投票

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

当应用程序尚未以能够处理底层数据库重新启动的方式编写时,就会发生这种情况。


1
投票

在我们的例子中,我们有一个查询,它使用 select * from x where Something in (...) 加载多个项目 这部分对于基准测试来说太长了。(17mb 作为文本查询)。查询有效,但文本太长。缩短查询解决了问题。


0
投票

我收到此错误,然后重新启动了在客户端应用程序和数据库之间保存连接池的 GlassFish 服务器,错误就消失了。因此,如果适用,请尝试重新启动应用程序服务器。


0
投票

我似乎通过删除参数化查询的参数占位符来修复我的实例。

由于某种原因,使用这些占位符工作正常,然后它们停止工作,我收到了错误/错误。

作为一种解决方法,我用文字替换了占位符,它开始工作。

删除这个

where 
    SOME_VAR = :1

用这个

where 
    SOME_VAR = 'Value'

0
投票

似乎是一个观点问题。 JDBC 查询正在使用视图。 我猜测了一下,重新编译了视图,错误就消失了。


-1
投票

就我而言,在 SQLdeveloper 中运行这样的简单查询时会发生错误:

select count(1) from tabel1 inner join tabel2 on table1.id = table2.id_table1 ; 

我解决了错误所以...

select 
/*+OPT_PARAM('_index_join_enabled' 'false') */  
count(1) from tabel1 inner join tabel2 on table1.id = table2.id_table1 ;
© www.soinside.com 2019 - 2024. All rights reserved.