1

データベース接続を正しく作成して閉じていることを確認するために、次のコードを書きました。これは、Oracle 10g XE インスタンスに接続する、Oracle シン クライアントのコア Java だけを含む単純な Java コードです。私は、このコードが問題なく実行されることを期待していました。これは、(単一のスレッドで) 接続を作成して閉じるだけだったからです。しかし、問題は、数回 (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 回ではなく、これを 1 回だけ実行すると、まったく問題なく動作することに注意してください。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

このシナリオの何が問題になっていますか?

私がやろうとしていることについてもっと詳しく知りたい場合は、ここでブログを書いています。

4

3 に答える 3

1

Ok。問題を発見しました。

仮説 - 接続を閉じるビットは、1. Java コード 2. データベース サーバーの 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();

    }
...
于 2012-10-16T03:48:59.450 に答える
0

このエラーは、リクエストを処理するために使用できるリスナーがないことを意味するため、接続が適切に閉じられていないと思います。ログに「接続が壊れています」というテキストが表示されていますか?

于 2012-10-15T11:06:27.533 に答える
0

おそらく接続が閉じられていません。Java にクロージングを任せることをお勧めします。を実装するAutoClosableインターフェースが追加されました。Connection詳細はこちら。これを試して、まだエラーが発生するかどうかを確認してください。可能であれば、API に作業を任せることをお勧めします。

于 2012-10-15T11:10:55.050 に答える