Question

Just to ensure that I am correctly creating and closing database connection, I wrote the following code. This is a simple java code with nothing but core java, Oracle thin client, connecting to Oracle 10g XE instance. I had expected this code to run without any problem - since it was just creating and closing connection (in a single thread) - many times over. But the problem is after running for a few times (20ish) it throws error.

The code:

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.");
            }
        }
    }
}

}

And the error it throws is

ORA-12519, TNS:no appropriate service handler found

Important to note, if I run this just once - not 100 times as shown in the code snippet above - it works absolutely fine. If I run it 100 times, it runs for a few time (20 - 25 times) and then exits with the error shown above. For example the snippet shows that many connections were open and were successfully closed, but immediately after that it starts throwing error.

    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

Any ideas, what is wrong with this scenario?

If you wanted more context on what exactly I am trying to do, I have blogged about it here.

Was it helpful?

Solution

Ok. Found out the issue.

Hypothesis - The connection closing bit is happening at two levels 1. the java code 2. the database server. In my code the java bit is closing connection quicker than the database server is able to close them (expected because it is really the database server which is doing most of the job there). Hence there is a bit of race condition, where the java code is assuming that previous connection is closed and is trying to create a new one, while the database server has not been able to close the previous connection yet.

Proof - if I make java code wait a bit after it has managed to close connection, then this code works fine. I had this modified piece of java code execute in a loop 1000 times over and it ran alright. Compare this with the fact that when I reported this issue, the code will only run about 20 - 25 times before tripping over.

The new code (just the modification) ...

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

    }
...

OTHER TIPS

I guess your connections aren't being closed properly, since that error means there are no available listeners to handle the request. Are you getting the "Connection broken" text in your log?

Probably your connections are not being closed. I would reocmmend you let java do the closing for you. There is now the AutoClosable interface which Connection implements. Details of it are here. Try with this and see if you still get the errors. It is always better to let the API do the work for you if possible.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top