This and similar questions were asked many times but none of the recommended setting work for me.
What I need is to configure the timeout for the case if the DB host is not available or Oracle DB is still not up and running.
I need to check the status of the Oracle DB server in Docker, so I am executing select 1 from dual
in a bash loop but the DriverManager.getConnection
returns (with the mentioned exception) after 20 seconds which is too much for me. I would like to reduce this timeout to 1 sec.
I know there is an Oracle tool, called TNSPING for checking the Oracle DB Server status, but unfortunately, this tool is not part of the official Oracle DB image and I do not want to install any Oracle product in Docker just because of TNSPING.
This is what I have tried so far, but the settings I use have no impact on this timeout.
The java.sql.SQLRecoverableException: IO Error: The Network Adapter could not establish the connection
exception appears after 20 sec. instead of 1 sec. Does not matter I use 1, 1000, or 10000 in the java code, the timeout is always 20 sec.
private Connection getConnection(String jdbcUrl) throws SQLException {
String timeout = "100";
Properties p = new Properties();
p.put(OracleConnection.CONNECTION_PROPERTY_THIN_NET_CONNECT_TIMEOUT, timeout);
p.put(OracleConnection.CONNECTION_PROPERTY_THIN_READ_TIMEOUT, timeout);
p.put(OracleConnection.CONNECTION_PROPERTY_THIN_JNDI_LDAP_CONNECT_TIMEOUT, timeout);
p.put(OracleConnection.CONNECTION_PROPERTY_THIN_JNDI_LDAP_READ_TIMEOUT, timeout);
p.put(OracleConnection.CONNECTION_PROPERTY_THIN_OUTBOUND_CONNECT_TIMEOUT, timeout);
p.put(OracleConnection.CONNECTION_PROPERTY_DOWN_HOSTS_TIMEOUT, timeout);
p.put("oracle.jdbc.ReadTimeout", timeout);
p.put("oracle.net.CONNECT_TIMEOUT", timeout);
p.put (OracleConnection.CONNECTION_PROPERTY_USER_NAME, user);
p.put (OracleConnection.CONNECTION_PROPERTY_PASSWORD, password);
System.setProperty("oracle.net.READ_TIMEOUT", timeout);
System.setProperty("oracle.jdbc.ReadTimeout", timeout);
System.setProperty("oracle.jdbc.javaNetNio", "true");
DriverManager.setLoginTimeout(Integer.valueOf(timeout));
Connection connection = DriverManager.getConnection(jdbcUrl, p);
connection.setNetworkTimeout(Executors.newSingleThreadExecutor(), Integer.valueOf(timeout));
return connection;
}
I do not want to add a connection pool solution to my simple app, only pure JDBC can be enough for me.
What I missed here?
-- UPDATE --
It seems that the issue is environment-specific and maybe not related to Java, but still not sure.
If I execute exactly the same command in my machine and in Docker then I get back total different execution times:
command:
$ time java -jar sql-runner-0.2.0-SNAPSHOT-with-dependencies.jar -j jdbc:oracle:thin:@//somehost:1521/somedb -U "doesnotmatter" -P "password" "select 1 from dual"
The result in docker:
IO Error: Unknown host specified
real 0m20.521s
user 0m0.764s
sys 0m0.097s
The result if I execute it on my machine:
IO Error: Unknown host specified
real 0m0.501s
user 0m0.715s
sys 0m0.095s
The complete source code is available here.
This behavior is so strange.