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

发布于 2024-11-09 10:05:36 字数 332 浏览 8 评论 0原文

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

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

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

知道发生了什么以及我能做些什么来避免它吗?

Yesterday evening I left the office with a running Java program written by me. It should insert a lot of records into our company database (Oracle) using a JDBC connection. This morning when I came back to work I saw this error (caught by a try-catch):

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

The program wrote almost all records before getting this problem, but what if it happens early (just minutes after I leave the office at evening)? I cannot understand what happened, I contacted my database admin and he said there was no particular issue on the database.

Any idea on what happened and what can I do do to avoid it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

厌味 2024-11-16 10:05:36

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

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

The error occurs on some RedHat distributions. The only thing you need to do is to run your application with parameter java.security.egd=file:///dev/urandom:

java -Djava.security.egd=file:///dev/urandom [your command]
眼角的笑意。 2024-11-16 10:05:36

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

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

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

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

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

如果您需要达到高质量的随机性水平,您可以可以用一个硬件代替您的 Linux 随机数生成器软件。

一些信息可在此处获取。

问候

托马斯

I want to produce a complementary answer of nacho-soriano's solution ...

I recently search to solve a problem where a Java written application (a Talend© ELT job in fact) want to connect to an Oracle database (11g and over) then randomly fail. OS is both RedHat Enterprise and CentOS. Job run very quily in time (no more than half a minute) and occur very often (approximately one run each 5 minutes).

Some times, during night-time as work-time, during database intensive-work usage as lazy work usage, in just a word randomly, connection fail with this message:

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 ...

##Problem explanation:##

As detailed here

Oracle connection needs some random numbers to assume a good level of security. Linux random number generator produce some numbers bases keyboard and mouse activity (among others) and place them in a stack. You will grant me, on a server, there is not a big amount of such activity. So it can occur that softwares use more random number than generator can produce.

When the pool is empty, reads from /dev/random will block until additional environmental noise is gathered. And Oracle connection fall in timeout (60 seconds by default).

##Solution 1 - Specific for one app solution##

The solution is to give add two parameters given to the JVM while starting:

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

Note: the '/./' is important, do not drop it !

So the launch command line could be:

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

One drawback of this solution is that numbers generated are a little less secure as randomness is impacted. If you don't work in a military or secret related industry this solution can be your.

##Solution 2 - General Java JVM solution##

As explained here

Both directives given in solution 1 can be put in Java security setting file.

Take a look at $JAVA_HOME/jre/lib/security/java.security

Change the line

securerandom.source=file:/dev/random

to

securerandom.source=file:/dev/urandom

Change is effective immediately for new running applications.

As for solution #1, one drawback of this solution is that numbers generated are a little less secure as randomness is impacted. This time, it's a global JVM impact. As for solution #1, if you don't work in a military or secret related industry this solution can be your.

We ideally should use "file:/dev/./urandom" after Java 5 as previous path will again point to /dev/random.

Reported Bug : https://bugs.openjdk.java.net/browse/JDK-6202721

##Solution 3 - Hardware solution##

Disclamer: I'm not linked to any of hardware vendor or product ...

If your need is to reach a high quality randomness level, you can replace your Linux random number generator software by a piece of hardware.

Some information are available here.

Regards

Thomas

故人爱我别走 2024-11-16 10:05:36

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

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

This simply means that something in the backend ( DBMS ) decided to stop working due to unavailability of resources etc.
It has nothing to do with your code or the number of inserts.
You can read more about similar problems here:

This may not answer your question, but you will get an idea of why it might be happening. You could further discuss with your DBA and see if there is something specific in your case.

你好,陌生人 2024-11-16 10:05:36

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

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

Ref :- https://community.oracle.com/thread/943911

Solution
Change the setup for your application, so you this parameter[-Djava.security.egd=file:/dev/../dev/urandom] next to the java command:

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

Ref :- https://community.oracle.com/thread/943911

無心 2024-11-16 10:05:36

从 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。

导出 JAVA_OPTS=" $JAVA_OPTS -Djava.security.egd=file:///dev/urandom "

We experienced these errors intermittently after upgraded from 11g to 12c and our java was on 1.6.

The fix for us was to upgrade java and jdbc from 6 to 7

export JAVA_HOME='/usr/java1.7'

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

Several days later, still intermittent connection resets.

We ended up removing all the java 7 above. Java 6 was fine. The problem was fixed by adding this to our user bash_profile.

Our groovy scripts that were experiencing the error were using /dev/random on our batch VM server. Below forced java and groovy to use /dev/urandom.

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

无尽的现实 2024-11-16 10:05:36

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

Your exception says it all "Connection reset".
The connection between your java process and the db server was lost, which could have happened for almost any reason(like network issues). The SQLRecoverableException just means that its recoverable, but the root cause is connection reset.

岁吢 2024-11-16 10:05:36

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

I had a similar situation when reading from Oracle in a Spark job. This connection reset error was caused by an incompatibility between the Oracle server and the JDBC driver used. Worth checking it.

反话 2024-11-16 10:05:36

在运行命令中添加 java security

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

add java security in your run command

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文