WebアプリケーションのデータベースとしてOracleを使用しています。ほとんどの場合、アプリケーションは正常に実行されますが、この「ソケットから読み取るデータはこれ以上ありません」というエラーが表示されます。
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.
このようなエラーの場合は、Oracleサポートが必要です。残念ながら、使用しているOracleリリースについては言及していません。このエラーは、オプティマイザーのバインドピークに関連している可能性があります。 Oracleのバージョンに応じて、異なる回避策が適用されます。
これに対処するには2つの方法があります。
_optim_peek_user_binds = false
を設定しますもちろん、アンダースコアパラメータは、Oracleサポートからアドバイスがあった場合にのみ設定する必要があります。
別のケース:パラメーター化された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);
2つのことを試してください。
Java/jdk1.6.0_31/jre/lib/security/Java.security
でsecurerandom.source=file:/dev/urandom
をsecurerandom.source=file:///dev/urandom
に変更します同じ問題がありました。次のシナリオで、アプリケーション側から問題を解決できました。
JDK8、Spring Framework 4.2.4.RELEASE、Apache Tomcat 7.0.63、Oracle Database 11g Enterprise Edition 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
JREを7から6にダウングレードすると、この問題は修正されました。
これは非常に低レベルの例外で、ORA-17410です。
いくつかの理由で発生する可能性があります。
ネットワークの一時的な問題。
JDBCドライバーのバージョンが間違っています。
特別なデータ構造に関するいくつかの問題(データベース側)。
データベースのバグ。
私の場合、それはデータベースにヒットしたバグであり、パッチを適用する必要があります。
この場合、select * from xで複数のアイテムをロードするクエリがありました。ここで(...)in部分はベンチマークテストに非常に長かったです(テキストクエリとして17mb)。クエリは有効ですが、テキストが長すぎます。クエリを短くすることで問題は解決しました。
はい、@ ggkmathが言ったように、古き良き再起動がまさにあなたが必要とするものです。 「著者に連絡してアプリを書き直してもらいながら、しばらく待つ」という選択肢はありません。
これは、基礎となるデータベースの再起動を処理できるようにアプリケーションが(まだ)書き込まれていない場合に発生します。
パラメーター化されたクエリのパラメータープレースホルダーを削除して、インスタンスを修正したようです。
何らかの理由で、これらのプレースホルダーを使用すると正常に機能し、動作しなくなり、エラー/バグが発生しました。
回避策として、プレースホルダーの代わりにリテラルを使用し、機能し始めました。
これを削除
where
SOME_VAR = :1
これを使って
where
SOME_VAR = 'Value'