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

时间:2011-01-31 12:39:21

标签: java timeout database-connection

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

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

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

感谢任何帮助。

5 个答案:

答案 0 :(得分:5)

如果没有其他选项,你可以随时在一个单独的线程中执行该调用,如果它在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秒,但是当线程完成时将其更改为立即返回并不太难。

答案 1 :(得分:2)

您可以使用Java的ExecutorService接口。以下是您需要做的样本。

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

答案 2 :(得分:1)

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

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

<jdbc-connection-pool 
                     connection-validation-method="table"
                     fail-all-connections="true"
                     idle-timeout-in-seconds="300"
                     is-connection-validation-required="true"
                     statement-timeout-in-seconds="2"
                     validation-table-name="dual"
                     ..... >
   <property name="databaseName" value="...."/>
   <property name="serverName" value="....."/>
   <property name="User" value="....."/>
   <property name="Password" value="......."/>
   <property name="URL" value="jdbc:mysql://...../...."/>
   <property name="driverClass" value="...."/>
   <property name="socketTimeout" value="2000"/>
</jdbc-connection-pool>

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

答案 3 :(得分:0)

答案 4 :(得分:0)

感谢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) {....