#oracle #hibernate #spring #jdbc
#Oracle #спящий режим #весна #jdbc
Вопрос:
Мы используем 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:oraclediagrdbmsadsadstraceads_ora_3836.trc (incident=31653):
ORA-03137: TTC protocol internal error : [12333] [4] [195] [3] [] [] [] []
Incident details in: d:oraclediagrdbmsadsadsincidentincdir_31653ads_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:oraclediagrdbmsadsadstraceads_ora_860.trc (incident=31645):
ORA-03137: TTC protocol internal error : [12333] [4] [195] [3] [] [] [] []
Incident details in: d:oraclediagrdbmsadsadsincidentincdir_31645ads_ora_860_i31645.trc
Thu Oct 20 10:34:21 2011
Версия Oracle: 11.2.0.1.0
Комментарии:
1. Похоже, что ваш сервер Oracle грубо отключил соединение с вашим приложением, когда он читал какой-то набор результатов.
2. Эта ошибка, скорее всего, возникает в приложениях, которые используют пул подключений к базе данных. Эта ошибка возникает, когда приложение извлекает соединение, время ожидания которого истекло или оно остановлено, и использует его для подключения к базе данных.
3. @User67546 Я установил конфигурацию пула соединений для проверки соединения перед использованием. Разве это не должно игнорировать устаревшие соединения
4. Вы получаете точно такую же ошибку и стек?
5. keywords for google: in german: «Keine weiteren Daten aus Socket zu lesen»
Ответ №1:
Для подобных ошибок вам следует обратиться в службу поддержки oracle. К сожалению, вы не указываете, какой выпуск oracle вы используете. Ошибка может быть связана с подглядыванием привязки оптимизатора. В зависимости от версии oracle применяются различные обходные пути.
У вас есть два способа решить эту проблему:
- обновление до 11.2
- установите параметр oracle
_optim_peek_user_binds = false
Конечно, параметры подчеркивания следует устанавливать только по рекомендации службы поддержки oracle
Комментарии:
1. Связались с oracle, и это проблема _optim_peek_user_binds, и нам пришлось либо обновить, либо исправить ее.
2. Я все еще получаю эту ошибку на 11.2.0.2.0 — 64bit, после перезапуска oracle db — pool не восстанавливается..
3. Это сообщение об ошибке указывает на сбой на стороне сервера. Их много, поэтому без проверки журналов на стороне сервера любые исправления являются лишь предположением. Обновление до последней поддерживаемой версии клиента JDBC, вероятно, является хорошей идеей в большинстве случаев.
4. Замена моей установки Oracle на современную систему управления базами данных сработала для меня.
5. вход в stackoverflow только для повышения @ K. Комментарий AlanBates
Ответ №2:
Мы столкнулись с той же проблемой, мы решили ее путем увеличения initialSize
и maxActive
размера пула соединений.
Вы можете проверить эту ссылку
Может быть, это кому-то поможет.
Ответ №3:
Другой случай: если вы отправляете параметры даты в параметризованный 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);
Ответ №4:
Это исключение очень низкого уровня, которое является ORA-17410.
Это может произойти по нескольким причинам:
- Временная проблема с сетью.
- Неправильная версия драйвера JDBC.
- Некоторые проблемы со специальной структурой данных (на стороне базы данных).
- Ошибка базы данных.
В моем случае это была ошибка, с которой мы столкнулись в базе данных, которую необходимо исправить.
Ответ №5:
Попробуйте две вещи:
- Установите в $ORACLE_HOME/network/admin/tnsnames.ora на сервере oracle server server=выделенный для сервера = общий, чтобы разрешить более одного подключения одновременно. Перезапустите oracle.
- Если вы используете Java, это может вам помочь: В
java/jdk1.6.0_31/jre/lib/security/Java.security
измененииsecurerandom.source=file:/dev/urandom
наsecurerandom.source=file:///dev/urandom
Ответ №6:
У меня была та же проблема. Я смог решить проблему со стороны приложения по следующему сценарию:
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
Комментарии:
1. Я использую JDK1.8,SpringJDBCTemplate,OracleDB,SpringRestService amp; org.commons.dbcp.BasicDataSource. Периодически получаю эту ошибку. Возникнут ли у меня какие-либо проблемы при использовании указанных выше свойств?
Ответ №7:
Понижение JRE с 7 до 6 устранило эту проблему для меня.
Комментарии:
1. Просто мысль, может быть, это сработало из-за версии драйвера JDBC: 11.2.0.4 поддерживает JDK 6, 7 и 8, но 11.2.0.3 поддерживает только JDK 6 oracle.com/technetwork/apps-tech/jdbc-112010-090769.html
Ответ №8:
Да, как сказал @ggkmath, иногда старый добрый перезапуск — это именно то, что вам нужно. Например, когда «свяжитесь с автором и попросите его переписать приложение, а пока подождите» — это не вариант.
Это происходит, когда приложение не написано (пока) таким образом, чтобы оно могло обрабатывать перезапуски базовой базы данных.
Ответ №9:
В нашем случае у нас был запрос, который загружает несколько элементов с помощью select * from x, где что-то в (…) части in было таким длинным для эталонного теста. (17 МБ в качестве текстового запроса). Запрос действителен, но текст такой длинный. Сокращение запроса решило проблему.
Ответ №10:
Я получил эту ошибку, затем перезапустил свой сервер GlassFish, на котором находились пулы соединений между моим клиентским приложением и базой данных, и ошибка исчезла. Итак, попробуйте перезапустить сервер приложений, если это применимо.
Комментарии:
1. Да, проблема исчезает при перезапуске вашего приложения, но это не ответ на вопрос, и вы не можете продолжать выполнять перезапуски все время, пока они находятся в производстве.
2. На самом деле это совершенно законный ответ. Иногда при перезапуске БД зависящий сервер / приложение не обрабатывает его должным образом. Так что да, приложение должно быть исправлено, но это не поможет вам в тот момент, когда вам нужно, чтобы приложение отвечало. Перезапуск приложения выполняется.
3. @javagirl И на какой вопрос вы ссылаетесь? На самом деле OP не сформулировал ни одного вопроса. Он не спросил: «Как мы должны переписать приложение?» И этот ответ также не предполагает, что «это долгосрочное решение». Когда десятки людей ждут, когда приложение начнет отвечать, вы не говорите им «перепишите это».
Ответ №11:
Я, похоже, исправил свой экземпляр, удалив заполнитель параметра для параметризованного запроса.
По какой-то причине использование этих заполнителей работало нормально, а затем они перестали работать, и я получил ошибку / ошибку.
В качестве обходного пути я заменил литералы на свои заполнители, и он начал работать.
Удалите это
where
SOME_VAR = :1
Используйте это
where
SOME_VAR = 'Value'
Ответ №12:
Похоже, проблема с представлением. Запрос JDBC использовал представление. Я предположил, перекомпилировал представление, и ошибка исчезла.
Ответ №13:
В моем случае ошибка возникает при выполнении простого запроса, подобного этому, в 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 ;