gpt4 book ai didi

java - 在数据库链接失败后恢复 jdbc 连接

转载 作者:搜寻专家 更新时间:2023-11-01 02:47:41 24 4
gpt4 key购买 nike

访问断开的远程数据库的数据库链接后,能否恢复JDBC数据库连接?我们有一个应用程序使用到(本地)oracle 数据库的单个连接,但偶尔会通过数据库链接(REMOTE_DB)从远程数据库读取数据。问题是,如果远程数据库由于某种原因(网络断开)脱机,在访问数据库链接后,jdbc 连接将变得不可用。我执行以下三个 SQL 语句:

1. SELECT 1 FROM DUAL@REMOTE_DB => ok
<<Network failure>>
2. SELECT 1 FROM DUAL@REMOTE_DB => SQLException.
3. SELECT 1 FROM DUAL => SQLException.

与语句 2 和 3 一起发生的 JDBC 驱动程序 ojdbc6.jar 的特定 Java 异常是

    java.sql.SQLRecoverableException: No more data to read from socket
at oracle.jdbc.driver.T4CMAREngine.unmarshalUB1(T4CMAREngine.java:1185)

我认为这种行为不是“设计使然”的原因是,当我使用 SQLPlusPerl DBI 执行相同的序列时,不会出现相同的问题。使用多个版本的 Oracle 瘦 JDBC 驱动程序的 Oracle 11 会出现此问题。以下 java 程序可用于重现该问题。

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;


public class TestJdbc {
private static Connection connect() throws Exception {
String jdbcURL = "jdbc:oracle:thin:@localhost:1521:TNSNAME";
String user = "scott" ;
String passwd ="tiger";

Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
return DriverManager.getConnection(jdbcURL,user,passwd);
}

public static void main(String[] args) throws Exception {
Connection conn = connect();
PreparedStatement stServer = conn.prepareStatement("SELECT 'server' FROM DUAL@REMOTE_DB");
PreparedStatement stClient = conn.prepareStatement("SELECT 'client' FROM DUAL");
ResultSet resultSet;

try {
stServer.execute();
resultSet = stServer.getResultSet();
if (resultSet.next()) {
System.out.println("server: " + resultSet.getString(1));
}
} catch (SQLException e) {
System.out.println("exception on server link: " + e);
}
// force network disconnect here and press enter
BufferedReader lineOfText = new BufferedReader(new InputStreamReader(System.in));
lineOfText.readLine();

try {
stServer.execute();
resultSet = stServer.getResultSet();
if (resultSet.next()) {
System.out.println("server: " + resultSet.getString(1));
}
} catch (SQLException e) {
//SQLRecoverableException occurs here
System.out.println("exception on server link: " + e);
}
// press enter again
lineOfText.readLine();

try {
stClient.execute();
resultSet = stClient.getResultSet();
if (resultSet.next()) {
System.out.println("client: " + resultSet.getString(1));
}
} catch (SQLException e) {
System.out.println("exception on client connection: " + e);
}

stServer.close();
stClient.close();
}

}

关闭并重新打开连接将解决问题,但最好不要这样做,因为发生错误时我们可能正在处理事务。

编辑:请注意,使用 SQLPlus 我可以执行以下操作,这是使用 JDBC 连接池无法解决的问题:

SQL> update my_table set ...;

1 row updated.

SQL> select * from dual@REMOTE_DB;

D
-
X

<<Network failure>>

SQL> select * from dual@REMOTE_DB;
select * from dual@REMOTE_DB
*
ERROR at line 1:
ORA-12545: Connect failed because target host or object does not exist


SQL> update my_table set ...;

1 row updated.

SQL> commit;

Commit complete.

SQL>

最佳答案

使用连接池,例如 Apache DBCP http://commons.apache.org/proper/commons-dbcp/他们自动恢复失败的连接。它也是处理数据库连接的首选方式。

关于java - 在数据库链接失败后恢复 jdbc 连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18458764/

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