SQLRecoverableException:I / O异常:连接重置

时间:2011-05-24 12:29:02

标签: java oracle ioexception connection-reset

昨天晚上,我离开了办公室,运行了一个由我编写的Java程序。它应该使用JDBC连接将大量记录插入到我们的公司数据库(Oracle)中。今天早上当我回来工作时,我看到了这个错误(被try-catch捕获):

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

该程序在得到这个问题之前写了几乎所有的记录,但如果它发生得很早(我晚上离开办公室几分钟后)怎么办?我无法理解发生了什么,我联系了我的数据库管理员,他说数据库没有特别的问题。

对发生的事情有什么想法,我该怎么办才能避免它?

8 个答案:

答案 0 :(得分:23)

某些RedHat发行版上发生错误。您唯一需要做的就是使用参数 java.security.egd = file:/// dev / urandom 运行您的应用程序:

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

答案 1 :(得分:13)

这只是意味着后端(DBMS)中的某些东西由于资源不可用而决定停止工作。 它与您的代码或插入数量无关。 您可以在此处阅读有关类似问题的更多信息:

这可能无法解答您的问题,但您会了解为什么会发生这种情况。您可以与您的DBA进一步讨论,看看您的案例中是否有特定的内容。

答案 2 :(得分:11)

我想提出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 ...

问题解释:

详细here

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解决方案

正如here

所解释的那样

解决方案1中给出的两个指令都可以放在Java安全设置文件中。

查看$JAVA_HOME/jre/lib/security/java.security

更改行

securerandom.source=file:/dev/random

securerandom.source=file:/dev/urandom

更改对新运行的应用程序立即生效。

对于解决方案#1,此解决方案的一个缺点是随着随机性的影响,生成的数字安全性稍差。这一次,它是全球JVM的影响。至于解决方案#1,如果你不在军事或秘密相关行业工作,这个解决方案可以是你的。

理想情况下,我们应该在Java 5之后使用“file:/ dev /./ urandom”,因为之前的路径将再次指向/ dev / random。

报告错误:https://bugs.openjdk.java.net/browse/JDK-6202721

解决方案3 - 硬件解决方案

Disclamer:我没有与任何硬件供应商或产品相关联......

如果您需要达到高质量的随机性级别,您可以通过硬件更换Linux随机数生成器软件。

有些信息可供here

此致

托马斯

答案 3 :(得分:5)

解决方案
更改应用程序的设置,因此java命令旁边的参数[ -Djava.security.egd = file:/ dev /../ dev / urandom ]:

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

参考: - https://community.oracle.com/thread/943911

答案 4 :(得分:4)

我们在从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脚本在我们的批处理VM​​服务器上使用/ dev / random。下面强制java和groovy使用/ dev / urandom。

export JAVA_OPTS =“$ JAVA_OPTS -Djava.security.egd = file:/// dev / urandom”

答案 5 :(得分:2)

您的例外说明了所有“连接重置”。 您的Java进程和数据库服务器之间的连接已丢失,这几乎可能是出于任何原因(如网络问题)。 SQLRecoverableException只是意味着它是可恢复的,但根本原因是连接重置。

答案 6 :(得分:1)

在Spark作业中从Oracle读取时,我遇到了类似的情况。此连接重置错误是由Oracle服务器与所使用的JDBC驱动程序之间的不兼容引起的。值得检查。

答案 7 :(得分:0)

在运行命令中添加Java安全性

java -jar -Djava.security.egd="file:///dev/urandom" yourjarfilename.jar