如何强制超时为DriverManager.getConnection()方法调用?

我有一个应用程序,它将与MySQL建立数据库连接并执行查询。 有时, DriverManager.getConnection()方法调用需要2秒,有时需要30秒。 有没有办法控制此方法2秒后超时?

DriverManager.setLoginTimeout()似乎不起作用。

实际上,我可以通过将线程hibernate为超时值并在唤醒后关闭连接来为statement.executeQuery()设置超时。 但它的连接建立部分我无法真正设置超时。

非常感谢任何帮助。

如果没有其他选项,您可以始终只在一个单独的线程中执行调用,如果它在2秒内没有完成,您将中止/忽略该线程。

编辑这是我的想法的一个例子:

 public class Dummy extends Thread { private volatile Connection conn = null; @Override public void run() { try { this.conn = DriverManager.getConnection("foobar") ; } catch (SQLException e) { e.printStackTrace(); } } static public Connection getConnection() { Dummy d = new Dummy() ; d.start() ; try { Thread.sleep(2000) ; } catch (InterruptedException e) {} return d.conn ; } } 

然后,您可以在代码中的其他位置调用静态Dummy.getConnection()方法。 一个缺点是这种方法总是花费2秒,但是当线程完成时将其更改为立即返回并不太难。

您可以使用Java中的ExecutorService接口。 以下是您需要做的事情的示例。

 Future future = executor.submit(YOUR_METHOD); future.get(TIMEOUT_YOU_NEED, TimeUnit.SECONDS); 

尝试在连接URL或连接池上设置socketTimeout(以毫秒为单位的时间)(如果使用池)。 注意不要将此值设置得太低,否则会覆盖语句超时值。

 try { this.conn = DriverManager.getConnection("url?socketTimeout=2000") ; } catch (SQLException e) { e.printStackTrace(); } 

要么

          

设置此项修复了我的超时问题。

感谢codebolt,我不知道它是否是最好的解决方案,但这对我有用。 10秒超时。

 public class Dummy extends Thread { private volatile java.sql.Connection conn = null; private boolean sleep = true; @Override public void run() { try { String driver = "net.sourceforge.jtds.jdbc.Driver"; Class.forName(driver).newInstance(); //timeout DriverManager.setLoginTimeout(10); this.conn = DriverManager.getConnection(url, user, pwd); sleep = false; } catch (Exception e) {} } public java.sql.Connection getConnection() { Dummy d = new Dummy() ; d.start() ; try { for(int i=1; i<=10; i++) { //Wait 1 second if (d.sleep){ Thread.sleep(1000); } } } catch (InterruptedException e) {} return d.conn ; } } 

电话:

 Dummy a = new Dummy(); connection = a.getConnection(); if (connection != null) {.... 

我扩展了CodeBolt和anpadia的答案,以完成以下完整课程。 它只有一个静态方法接受所有需要的连接参数,包括超时持续时间。 此外,如果出现SQLException和ClassNotFoundException,该方法也会抛出。

用法:

 String connectionUrl = "..."; String user = "..."; String password = "..."; String driver = "org.postgresql.Driver"; // for example int timeoutInSeconds = 5; Connection myConnection = ConnectWithTimeout.getConnection(connectionUrl, user, password, driver, timeoutInSeconds); 

以下是实施:

 import java.sql.DriverManager; import java.sql.Connection; import java.sql.SQLException; public class ConnectWithTimeout extends Thread { private static String _url; private static String _user; private static String _password; private static String _driver; private static volatile Connection _connection = null; private static volatile boolean _sleep = true; private static volatile SQLException _sqlException = null; private static volatile ClassNotFoundException _classNotFoundException = null; @Override public void run() { try { Class.forName(_driver); _connection = DriverManager.getConnection(_url, _user, _password); } catch (SQLException ex) { _sqlException = ex; } catch (ClassNotFoundException ex) { _classNotFoundException = ex; } _sleep = false; } public static Connection getConnection(String url, String user, String password, String driver, int timeoutInSeconds) throws SQLException, ClassNotFoundException { checkStringOrThrow(url, "url"); checkStringOrThrow(user, "user"); checkStringOrThrow(password, "password"); checkStringOrThrow(driver, "driver"); if (timeoutInSeconds < 1) { throw new IllegalArgumentException( "timeoutInSeconds must be positive"); } _url = url; _user = user; _password = password; _driver = driver; ConnectWithTimeout conn = new ConnectWithTimeout(); conn.start(); try { for (int i = 0; i < timeoutInSeconds; i++) { if (_sleep) { Thread.sleep(1000); } } } catch (InterruptedException ex) { } if (_sqlException != null) { throw _sqlException; } if (_classNotFoundException != null) { throw _classNotFoundException; } return _connection; } private static void checkStringOrThrow(String variable, String variableName) { if (variable == null || variable.length() == 0) { throw new IllegalArgumentException( "String is null or empty: " + variableName); } } }