SQLRecoverableException: исключение ввода-вывода: соединение reset

Вчера вечером я покинул офис с запущенной программой Java, написанной мной. Он должен вставить много записей в нашу базу данных нашей компании (Oracle), используя соединение JDBC. Сегодня утром, когда я вернулся на работу, я увидел эту ошибку (пойманную попыткой):

java.sql.SQLRecoverableException: I/O Exception: Connection reset

Программа написала почти все записи перед тем, как решить эту проблему, но что, если это произойдет раньше (через несколько минут после того, как я покидаю офис вечером)? Я не могу понять, что произошло, я связался с администратором базы данных и сказал, что в базе данных нет особых проблем.

Любая идея о том, что произошло, и что я могу сделать, чтобы избежать этого?

Ответ 1

Это просто означает, что что-то в бэкэнд (СУБД) решило прекратить работу из-за недоступности ресурсов и т.д. Это не имеет никакого отношения к вашему коду или количеству вставок. Вы можете узнать больше о подобных проблемах здесь:

Это может не ответить на ваш вопрос, но вы поймете, почему это может произойти. Вы можете обсудить с вашим администратором базы данных и посмотреть, есть ли что-то конкретное в вашем случае.

Ответ 2

Ошибка возникает в некоторых дистрибутивах RedHat. Единственное, что вам нужно сделать, это запустить приложение с параметром java.security.egd = file:///dev/urandom:

java -Djava.security.egd=file:///dev/urandom [your command]

Ответ 3

Я хочу дать дополнительный ответ о решении nacho-soriano...

Недавно я пытался решить проблему, когда написанное на Java приложение (на самом деле это задание Talend ELT) хочет подключиться к базе данных Oracle (11g и более), а затем случайно произойдет сбой. Операционная система RedHat Enterprise и CentOS. Задание выполняется очень быстро во времени (не более полминуты) и выполняется очень часто (приблизительно один запуск каждые 5 минут).

Иногда, в ночное время как рабочее время, во время интенсивного использования базы данных в виде ленивого использования, одним словом, случайным образом, происходит сбой соединения с этим сообщением:

Exception in component tOracleConnection_1
java.sql.SQLRecoverableException: Io exception: Connection reset
        at oracle.jdbc.driver.SQLStateMapping.newSQLException(SQLStateMapping.java:101)
        at oracle.jdbc.driver.DatabaseError.newSQLException(DatabaseError.java:112)
        at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:173)
        at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:229)
        at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:458)
        at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:411)
        at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:490)
        at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:202)
        at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:33)
        at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:465)
        at java.sql.DriverManager.getConnection(DriverManager.java:664)
        at java.sql.DriverManager.getConnection(DriverManager.java:208)
    and StackTrace follow ...

Объяснение проблемы:

Как подробно здесь

Для соединения Oracle необходимы случайные числа, чтобы обеспечить хороший уровень безопасности. Генератор случайных чисел в Linux генерирует некоторые числа, основанные на активности клавиатуры и мыши (среди прочих), и помещает их в стек. Вы дадите мне, на сервере, нет большого количества такой деятельности. Так что может случиться так, что программы используют больше случайных чисел, чем может произвести генератор.

Когда пул пуст, чтение из /dev/random будет блокироваться, пока не будет собран дополнительный шум окружающей среды. И соединение Oracle падает в тайм-аут (60 секунд по умолчанию).

Решение 1 - Специально для одного приложения

Решение состоит в том, чтобы добавить два параметра, заданные JVM при запуске:

-Djava.security.egd=file:/dev/./urandom
-Dsecurerandom.source=file:/dev/./urandom

Примечание: "/./" важно, не бросайте его!

Таким образом, командная строка запуска может быть:

java -Djava.security.egd=file:/dev/./urandom -Dsecurerandom.source=file:/dev/./urandom -cp <classpath directives> appMainClass <app options and parameters>

Одним из недостатков этого решения является то, что сгенерированные числа являются немного менее безопасными из-за влияния случайности. Если вы не работаете в военной или секретной отрасли, это решение может быть вашим.

Решение 2 - Общее решение Java JVM

Как объяснено здесь

Обе директивы, приведенные в решении 1, могут быть помещены в файл настроек безопасности Java.

Взгляните на $JAVA_HOME/jre/lib/security/java.security

Изменить линию

securerandom.source=file:/dev/random

в

securerandom.source=file:/dev/urandom

Изменение вступает в силу немедленно для новых запущенных приложений.

Что касается решения № 1, то одним из недостатков этого решения является то, что сгенерированные числа немного менее безопасны из-за влияния случайности. На этот раз это глобальное влияние JVM. Что касается решения № 1, если вы не работаете в военной или секретной отрасли, это решение может быть вашим.

В идеале мы должны использовать "file: /dev/./urandom" после Java 5, так как предыдущий путь снова будет указывать на /dev/random.

Отмеченная ошибка: https://bugs.openjdk.java.net/browse/JDK-6202721

Решение 3 - Аппаратное решение

Отказ от ответственности: я не связан ни с одним из поставщиков оборудования или продукта...

Если вам нужно достичь высокого уровня случайности, вы можете заменить программное обеспечение вашего генератора случайных чисел в Linux аппаратным обеспечением.

Некоторая информация доступна здесь.

С уважением

Томас

Ответ 4

Решение
Измените настройку для своего приложения, чтобы вы указали этот параметр [ -Djava.security.egd = file: /dev/../dev/urandom ] рядом с командой java:

Java -Djava.security.egd = файл: /dev/../dev/urandom [ваша команда]

Ссылка: - https://community.oracle.com/thread/943911

Ответ 5

Мы переживали эти ошибки с перерывами после обновления с 11g до 12c, а наш java был на 1.6.

Исправить для нас было обновление java и jdbc с 6 до 7

export JAVA_HOME='/usr/java1.7'

export CLASSPATH=/u01/app/oracle/product/12.1.0/dbhome_1/jdbc/libojdbc7.jar:$CLASSPATH 

Несколько дней спустя все еще прерывается соединение.

Мы закончили удаление всех java 7 выше. Java 6 в порядке. Проблема была устранена добавлением этого к нашему пользователю bash_profile.

Наши скрипты groovy, которые испытывали ошибку, использовали /dev/random на нашем пакетном сервере VM. Ниже принудительно java и groovy использовать /dev/urandom.

export JAVA_OPTS = "$ JAVA_OPTS -Djava.security.egd = файл:///dev/urandom"

Ответ 6

Ваше исключение говорит обо всем "Connection reset". Связь между вашим java-процессом и сервером db была потеряна, что могло произойти практически по любой причине (например, по сетевым проблемам). SQLRecoverableException просто означает, что его восстанавливаемая, но основной причиной является соединение reset.