Java + Oracle 连接 - 完成少量后被拒绝

标签 java ojdbc

为了确保我正确创建和关闭数据库连接,我编写了以下代码。这是一个简单的 java 代码,只有核心 java、Oracle 瘦客户端、连接到 Oracle 10g XE 实例。我原本期望这段代码运行时没有任何问题 - 因为它只是创建和关闭连接(在单个线程中) - 多次。但问题是运行几次(20ish)后它会抛出错误。

代码:

public class TestConnection {
private final static Logger logger = LoggerFactory
        .getLogger(TestConnection.class);

@Rule
public ContiPerfRule i = new ContiPerfRule();

@Test
@PerfTest(invocations = 100, threads = 1)
@Required(max = 1200, average = 1000)
public void test() {

    Connection connection = null;
    try {
        // Load the JDBC driver
        String driverName = "oracle.jdbc.driver.OracleDriver";
        Class.forName(driverName);

        // Create a connection to the database
        String serverName = "127.0.0.1";
        String portNumber = "1521";
        String sid = "XE";
        String url = "jdbc:oracle:thin:@" + serverName + ":" + portNumber
                + ":" + sid;
        String username = "funngames";
        String password = "funngames";
        connection = DriverManager.getConnection(url, username, password);
        assertNotNull(connection);
        logger.debug("Connection made.");

    } catch (ClassNotFoundException e) {
        logger.debug(e.getMessage());
    } catch (SQLException e) {
        logger.debug(e.getMessage());
    } finally {
        if (connection != null) {
            try {
                connection.close();
                logger.debug("Connection broken.");
            } catch (SQLException e) {
                logger.debug(e.getMessage());
                fail("The connection could not be closed.");
            }
        }
    }
}

}

它抛出的错误是

ORA-12519, TNS:no appropriate service handler found

重要的是要注意,如果我只运行一次(而不是上面的代码片段所示的 100 次),它绝对可以正常工作。如果我运行它 100 次,它会运行几次(20 - 25 次),然后退出并出现上面显示的错误。例如,该代码片段显示许多连接已打开并已成功关闭,但此后它立即开始抛出错误。

    foo.bar.database.TestConnection.test
16:39:17.854 [main] DEBUG foo.bar.database.TestConnection - Connection made.
16:39:17.854 [main] DEBUG foo.bar.database.TestConnection - Connection broken.
16:39:17.869 [main] DEBUG foo.bar.database.TestConnection - Connection made.
16:39:17.869 [main] DEBUG foo.bar.database.TestConnection - Connection broken.
16:39:17.885 [main] DEBUG foo.bar.database.TestConnection - Connection made.
16:39:17.885 [main] DEBUG foo.bar.database.TestConnection - Connection broken.
16:39:17.901 [main] DEBUG foo.bar.database.TestConnection - Connection made.
16:39:17.901 [main] DEBUG foo.bar.database.TestConnection - Connection broken.
16:39:17.916 [main] DEBUG foo.bar.database.TestConnection - Connection made.
16:39:17.916 [main] DEBUG foo.bar.database.TestConnection - Connection broken.
16:39:17.932 [main] DEBUG foo.bar.database.TestConnection - Connection made.
16:39:17.932 [main] DEBUG foo.bar.database.TestConnection - Connection broken.
16:39:17.948 [main] DEBUG foo.bar.database.TestConnection - Connection made.
16:39:17.948 [main] DEBUG foo.bar.database.TestConnection - Connection broken.
16:39:17.979 [main] DEBUG foo.bar.database.TestConnection - Connection made.
16:39:17.979 [main] DEBUG foo.bar.database.TestConnection - Connection broken.
16:39:17.994 [main] DEBUG foo.bar.database.TestConnection - Connection made.
16:39:17.994 [main] DEBUG foo.bar.database.TestConnection - Connection broken.
16:39:18.010 [main] DEBUG foo.bar.database.TestConnection - Connection made.
16:39:18.010 [main] DEBUG foo.bar.database.TestConnection - Connection broken.
16:39:18.026 [main] DEBUG foo.bar.database.TestConnection - Connection made.
16:39:18.026 [main] DEBUG foo.bar.database.TestConnection - Connection broken.
16:39:18.041 [main] DEBUG foo.bar.database.TestConnection - Connection made.
16:39:18.041 [main] DEBUG foo.bar.database.TestConnection - Connection broken.
16:39:18.057 [main] DEBUG foo.bar.database.TestConnection - Connection made.
16:39:18.057 [main] DEBUG foo.bar.database.TestConnection - Connection broken.
16:39:18.073 [main] DEBUG foo.bar.database.TestConnection - Connection made.
16:39:18.073 [main] DEBUG foo.bar.database.TestConnection - Connection broken.
16:39:18.088 [main] DEBUG foo.bar.database.TestConnection - Connection made.
16:39:18.088 [main] DEBUG foo.bar.database.TestConnection - Connection broken.
16:39:18.104 [main] DEBUG foo.bar.database.TestConnection - Connection made.
16:39:18.104 [main] DEBUG foo.bar.database.TestConnection - Connection broken.
16:39:18.119 [main] DEBUG foo.bar.database.TestConnection - Connection made.
16:39:18.119 [main] DEBUG foo.bar.database.TestConnection - Connection broken.
16:39:18.135 [main] DEBUG foo.bar.database.TestConnection - Connection made.
16:39:18.135 [main] DEBUG foo.bar.database.TestConnection - Connection broken.
16:39:18.151 [main] DEBUG foo.bar.database.TestConnection - Connection made.
16:39:18.151 [main] DEBUG foo.bar.database.TestConnection - Connection broken.
16:39:18.166 [main] DEBUG foo.bar.database.TestConnection - Listener refused the connection with the following error:
ORA-12519, TNS:no appropriate service handler found
The Connection descriptor used by the client was:
127.0.0.1:1521:XE

有什么想法吗,这个场景有什么问题吗?

如果您想了解更多关于我到底想做什么的背景信息,我有 blogged关于它在这里。

最佳答案

好的。发现问题了。

假设 - 连接关闭位发生在两个级别 1. java 代码 2. 数据库服务器。在我的代码中,java位关闭连接的速度比数据库服务器能够关闭它们的速度快(预期是因为它实际上是数据库服务器在那里完成了大部分工作)。因此,存在一些竞争条件,其中 java 代码假设前一个连接已关闭并尝试创建一个新连接,而数据库服务器尚未能够关闭前一个连接。

证明 - 如果我让 java 代码在成功关闭连接后稍等一下,那么这段代码就可以正常工作。我让这段修改过的 Java 代码在循环中执行了 1000 次,并且运行正常。与此相比,当我报告此问题时,代码只会运行大约 20 - 25 次才会出错。

新代码(只是修改)...

...
finally {
if (connection != null) {
    try {
        connection.close();
        logger.debug("Connection broken.");
        Thread.sleep(1000);
    } catch (SQLException e) {
        logger.debug(e.getMessage());
        e.printStackTrace();
        fail("The connection could not be closed.");
    } catch (InterruptedException e) {
        logger.debug(e.getMessage());
        e.printStackTrace();

    }
...

关于Java + Oracle 连接 - 完成少量后被拒绝,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12894193/

相关文章:

intellij-idea - IntelliJ IDE Spark 项目中的 Java.lang.ClassNotFoundException : oracle. jdbc.driver.OracleDriver

java - 如何将字符串数组转换为字节数组? ( java )

java - 对 2 个数组列表进行排序的最佳方法?

java - Oracle JDBC 类型通过 getObject() 映射到 Java 对象类型 - 错误的文档?

oracle - 无法使用 Sqoop 将数据从 Oracle 导入到 HDFS

java - 在文本字段中验证 PIN 码

java - 登录功能改进并解决循环问题

java - 如何在 Java 中格式化 ISO-8601

Java - 如何使用枚举

jdbc - 如何在Gradle项目中使用Oracle JDBC驱动程序