gpt4 book ai didi

java - Oracle JDBC 间歇性连接问题

转载 作者:IT老高 更新时间:2023-10-28 20:21:52 26 4
gpt4 key购买 nike

我遇到了一个非常奇怪的问题这是一个非常简单的使用JDBC连接Oracle数据库的方法

OS: Ubuntu
Java Version: 1.5.0_16-b02
1.6.0_17-b04
Database: Oracle 11g Release 11.1.0.6.0

当我使用 jar 文件时OJDBC14.jar 每次都连接数据库当我使用 jar 文件时OJDBC5.jar 它有时会连接,有时会抛出错误(如下所示)如果我用 Java 6 重新编译并使用OJDBC6.jar 我得到与 OJDBC5.jar

相同的结果

我需要 JODB5.jar 中的特定功能,而 OJDBC14.jar 中没有这些功能

任何想法

错误

> Connecting to oracle
java.sql.SQLException: Io exception: Connection reset
at oracle.jdbc.driver.SQLStateMapping.newSQLException(SQLStateMapping.java:74)
at oracle.jdbc.driver.DatabaseError.newSQLException(DatabaseError.java:110)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:171)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:227)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:494)
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:474)
at java.sql.DriverManager.getConnection(DriverManager.java:525)
at java.sql.DriverManager.getConnection(DriverManager.java:171)
at TestConnect.main(TestConnect.java:13)

代码

下面是我正在使用的代码

import java.io.*;
import java.sql.*;
public class TestConnect {
public static void main(String[] args) {
try {
System.out.println("Connecting to oracle");
Connection con=null;
Class.forName("oracle.jdbc.driver.OracleDriver");
con=DriverManager.getConnection(
"jdbc:oracle:thin:@172.16.48.100:1535:sample",
"JOHN",
"90009000");
System.out.println("Connected to oracle");
con.close();
System.out.println("Goodbye");
} catch(Exception e) { e.printStackTrace(); }
}
}

最佳答案

在一些 OTN 论坛 (https://kr.forums.oracle.com/forums/thread.jspa?messageID=3699989) 中提供了此问题的解决方案。但是,没有解释问题的根本原因。以下是我试图解释问题的根本原因。

Oracle JDBC 驱动程序以安全的方式与 Oracle 服务器通信。驱动程序使用 java.security.SecureRandom 类来收集熵以保护通信。此类依赖于原生平台支持来收集熵。

是由操作系统或应用程序收集/生成的随机性,用于密码学或其他需要随机数据的用途。这种随机性通常是从硬件源收集的,包括硬件噪声、音频数据、鼠标移动或专门提供的随机性生成器。内核收集熵并将其存储为一个熵池,并通过特殊文件 /dev/random/dev/random 将随机字符数据提供给操作系统进程或应用程序强>/dev/urandom

/dev/random 读取请求的比特/字节数量会耗尽熵池,从而提供加密操作中经常需要的高度随机性。如果熵池完全耗尽并且没有足够的熵可用,则 /dev/random 上的读取操作会阻塞,直到收集到额外的熵。因此,从 /dev/random 读取的应用程序可能会阻塞一段时间。

与上述相反,从 /dev/urandom 读取不会阻塞。从 /dev/urandom 读取也会耗尽熵池,但当熵不足时,它不会阻塞而是重用部分读取的随机数据中的位。据说这容易受到密码分析攻击。这是理论上的可能性,因此不鼓励从 /dev/urandom 中读取以收集密码操作中的随机性。

默认情况下,java.security.SecureRandom 类从 /dev/random 文件中读取,因此有时会随机阻塞一段时间。现在,如果读取操作在所需的时间内没有返回,Oracle 服务器会使客户端(在本例中为 jdbc 驱动程序)超时,并通过从其末端关闭套接字来中断通信。客户端从阻塞调用返回后尝试恢复通信时遇到 IO 异常。这个问题可能在任何平台上随机发生,尤其是在从硬件噪声中收集熵的平台上。

正如 OTN 论坛中所建议的,解决此问题的方法是覆盖 java.security.SecureRandom 类的默认行为以使用来自 /dev/urandom 的非阻塞读取 而不是从 /dev/random 阻塞读取。这可以通过向 JVM 添加以下系统属性 -Djava.security.egd=file:///dev/urandom 来完成。虽然这对于 JDBC 驱动程序等应用程序来说是一个很好的解决方案,但对于执行诸如加密 key 生成等核心加密操作的应用程序来说,这是不鼓励的。

其他解决方案可能是使用可用于平台的不同随机播种器实现,这些实现不依赖硬件噪声来收集熵。有了这个,您可能仍然需要覆盖 java.security.SecureRandom 的默认行为。

增加 Oracle 服务器端的套接字超时也是一种解决方案,但在尝试这样做之前,应从服务器的角度评估副作用。

关于java - Oracle JDBC 间歇性连接问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2327220/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com