[英]Timing out DriverManager.getConnection()?
我正在使用Java和mysql作为数据库,但遇到一个奇怪的问题:我的一个客户端连接非常不稳定,有时丢包率很高。 好的,我知道这不是软件的问题,但是我去了那里进行测试,并且当程序调用“ DriverManager.getConnection()”并且网络连接变得不稳定时,该行将锁定应用程序(或给定线程)几分钟。 我当然添加了一些逻辑,以便使用另一个数据源在本地缓存数据,然后在可能的情况下保存到网络主机,但是,我通常不能让程序挂起超过10秒钟(而且此方法似乎没有任何方法)。超时规范)。 因此,我想到了一种解决方法:
public class CFGBanco implements Serializable {
public String driver = "com.mysql.jdbc.Driver";
public String host;
public String url = "";
public String proto = "jdbc:mysql://";
public String database;
public String user;
public String password;
}
private static java.sql.Connection Connect(HostConfig dataHost) throws java.sql.SQLException, ClassNotFoundException
{
dataHost.url = dataHost.proto+dataHost.host;
if(dataHost.database != null && !dataHost.database.equals("")) dataHost.url += "/"+dataHost.database;
java.lang.Class.forName(dataHost.driver);
ArrayList<Object> lh = new ArrayList<>();
lh.add(0, null);
Thread ConThread = new Thread(()-> {
try {
lh.add(0, java.sql.DriverManager.getConnection(
dataHost.url, dataHost.user, dataHost.password));
} catch(Exception x ) {
System.out.println(x.getMessage());
}
}, "ConnThread-"+SessId);
ConThread.start();
Thread TimeoutThread = new Thread(() -> {
int c = 0;
int delay = 100;
try {
try {
do {
try {
if(t.isAlive())
Thread.sleep(delay);
else
break;
} catch(Exception x) {}
} while((c+=delay) < 10000);
} catch(Exception x){}
} finally {
try {
t.stop();
} catch(Exception x){}
}
}, "ConTimeout-"+SessId);
TimeoutThread.start();
try {
ConThread.join();
} catch(Exception x) {}
if(lh.get(0) == null)
throw new SQLException();
return (Connection) lh.get(0);
}
我从另一个线程调用getConnection,然后创建一个辅助“超时”线程来监视它,然后将调用线程加入ConThread。 确实,我一直在获得接近预期的结果,但令我感到困惑的是:是否有更好的方法来做到这一点? 创建2个线程是否会消耗大量系统资源,足以使这种方法不可行?
您需要连接池。 集中连接并重用它,而不是每次都重新创建。 一种用于数据库连接池的库是Apache的DBCP
它会照顾到何时断开连接等等。 您可以使用验证查询,并在从池中借用连接之前查询数据库提示,一旦验证成功,它将触发您的实际查询。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.