这个问题和类似的问题被问了很多次,但没有一个推荐的设置为我工作。
我需要的是在DB主机不可用或Oracle DB仍未启动和运行的情况下配置超时。
我需要检查Docker中的Oracle服务器的状态,所以我在bash循环中执行select 1 from dual
,但是DriverManager.getConnection
在20秒后返回(除了上述例外),这对我来说太大了。我想把这个超时时间缩短到1秒。
我知道有一个名为TNSPING的Oracle工具,用于检查Oracle DB Server状态,但不幸的是,该工具不是官方Oracle DB映像的一部分,我不想仅仅因为TNSPING而在Docker中安装任何Oracle产品。
到目前为止,这是我尝试过的,但是我使用的设置对这个超时没有影响。20秒后出现java.sql.SQLRecoverableException: IO Error: The Network Adapter could not establish the connection
异常。而不是1秒。不管我在java代码中使用1,1000或10000,超时时间总是20秒。
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;
}
我不想将连接池解决方案添加到我的简单应用程序中,只有纯JDBC才能满足我的需求。
我错过了什么?
--更新--
这个问题似乎是特定于环境的,可能与Java无关,但仍然不确定。
如果在机器和Docker中执行完全相同的命令,则返回完全不同的执行时间:
命令:
$ 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"
中的结果:
IO Error: Unknown host specified
real 0m20.521s
user 0m0.764s
sys 0m0.097s
如果我在我的机器上执行结果::
IO Error: Unknown host specified
real 0m0.501s
user 0m0.715s
sys 0m0.095s
完整的源代码是可用的这里。
这种行为太奇怪了。
发布于 2020-07-15 18:03:04
对您来说,这可能有各种不适用的原因:
您有以下选项来诊断您的问题:
绞刑:
strace -f -e trace=network -o strace.log 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"
启用调试的JDBC驱动程序(*_g.jar):
$ java -Doracle.jdbc.Trace=true \
-Djava.util.logging.config.file=Logging.properties \
-classpath "ojdbc8_g.jar:..." \
...
$ cat Logging.properties
.level=OFF
#.level=SEVERE
handlers=java.util.logging.FileHandler
# example of a full pathname in Windows
java.util.logging.FileHandler.pattern=Networkpacket.log
# Predefined levels are: ALL, SEVERE, WARNING, INFO, CONFIG, FINE, FINER,
# FINEST, OFF
java.util.logging.FileHandler.limit = 500000000
java.util.logging.FileHandler.count = 1
java.util.logging.FileHandler.level =ALL
java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
oracle.net.ns.level = ALL
## Following levels are commented to filter the network packet contents.
#oracle.jdbc.level=oFF
#oracle.jdbc.aq.level=OFF
#oracle.jdbc.driver.level=OFF
#oracle.jdbc.pool.level=OFF
#oracle.jdbc.rowset.level=OFF
#oracle.jdbc.xa.level=OFF
#oracle.sql.level=OFF
https://stackoverflow.com/questions/62892093
复制相似问题