我们能够解决问题。如编辑问题所述,只是在错误情况下删除连接是不可行的,因为我们可能正处于事务中。

事实证明,在每次执行后关闭PreparedStatement并在上面的示例程序中重新创建它会使问题消失。

除非您使用oracle implicit statement caching来提高性能,否则我们会这样做。

似乎问题只发生在oracle使用现有游标用于使用断开连接的服务器链接的语句时。问题似乎与JDBC的版本无关,但仅与Oracle 11g有关,而与早期版本的Oracle RDBMS无关。

因此解决方案包括禁用使用数据库链接的语句的语句缓存。

以下修改示例程序演示了解决方案。

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;

import oracle.jdbc.OracleConnection;

import oracle.jdbc.OraclePreparedStatement;

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();

OracleConnection conn = (OracleConnection) DriverManager.getConnection(jdbcURL,user,passwd);

// use implicit statement caching, so Oracle cursors are reused for

// frequent SQL statements

conn.setImplicitCachingEnabled(true);

conn.setStatementCacheSize(100);

return conn;

}

public static void main(String[] args) throws Exception {

Connection conn = connect();

ResultSet resultSet;

try {

PreparedStatement stServer = conn.prepareStatement("SELECT 'server' FROM DUAL@REMOTE_DB");

stServer.execute();

resultSet = stServer.getResultSet();

if (resultSet.next()) {

System.out.println("server: " + resultSet.getString(1));

}

resultSet.close();

// don't cache this statement, so calling it after a network

// failure will not destroy our connection

((OraclePreparedStatement)stServer).setDisableStmtCaching(true);

stServer.close();

} 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 {

PreparedStatement stServer = conn.prepareStatement("SELECT 'server' FROM DUAL@REMOTE_DB");

stServer.execute();

resultSet = stServer.getResultSet();

if (resultSet.next()) {

System.out.println("server: " + resultSet.getString(1));

}

resultSet.close();

((OraclePreparedStatement)stServer).setDisableStmtCaching(true);

stServer.close();

} catch (SQLException e) {

System.out.println("exception on server link: " + e);

}

// press enter again

lineOfText.readLine();

try {

PreparedStatement stClient = conn.prepareStatement("SELECT 'client' FROM DUAL");

stClient.execute();

resultSet = stClient.getResultSet();

if (resultSet.next()) {

System.out.println("client: " + resultSet.getString(1));

}

resultSet.close();

stClient.close();

} catch (SQLException e) {

System.out.println("exception on client connection: " + e);

}

}

}

Logo

一站式 AI 云服务平台

更多推荐