SQLRecoverableException:I / Oexception:连接重置

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

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

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

关于发生了什么以及我可以做些什么来避免它的任何想法?

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

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

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

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

在从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”

我想提出一个关于nacho-soriano解决方案的补充答案……

我最近搜索解决了Java编写的应用程序(事实上Talend的工作)想要连接到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.(PhysicalConnection.java:490) at oracle.jdbc.driver.T4CConnection.(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  appMainClass  

该解决方案的一个缺点是随着随机性的影响,生成的数字不太安全 。 如果您不在军事或秘密相关行业工作,这个解决方案可能是您的。

解决方案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,如果你不在军事或秘密相关行业工作,这个解决方案可以是你的。

解决方案3 – 硬件解决方案

免责声明:我没有链接任何硬件供应商或产品……

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

这里提供了一些信息。

问候

托马斯


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

java -Djava.security.egd = file:/ dev /../ dev / urandom [你的命令]

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

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