2011-01-31 45 views
7

私はMySQLとのDB接続を確立し、クエリを実行するアプリケーションを持っています。場合によってはDriverManager.getConnection()メソッド呼び出しに2秒かかり、場合によっては30秒かかります。このメソッドを2秒後にタイムアウトするように制御する方法はありますか?DriverManager.getConnection()メソッド呼び出しのタイムアウトを強制するには?

DriverManager.setLoginTimeout()は動作していないようです。

実際には、statement.executeQuery()のタイムアウトを設定することができます。タイムアウト値のスレッドをスリープして、ウェイクアップ後に接続を閉じることによって可能です。しかし、私は本当にタイムアウトを設定することはできませんでした接続確立の部分。

助けていただければ幸いです。ここで

+0

あなたが使用しているデータベースのためにされているドライバ? –

+0

私はjdbc mysqlドライバを使用します – ihavprobs

答えて

4

他のオプションはありません場合は、それが終了しない場合、あなたはいつもあなたが/無視中止別のスレッドで呼び出しを実行することができます2秒で

EDIT は、ここで私が考えていたものの例です:

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()メソッド他の場所を呼び出すことができます。 1つの欠点は、このメソッドは常に2秒かかることですが、スレッドが終了したときにすぐに戻るように変更することはあまり難しくありません。

+0

スレッドを中止する方法は? 2秒後にスレッドを中断することはできません。 – ihavprobs

+0

もしあなたがスレッドを中断しなければならないと思うなら、あなたはいつもstop()を呼び出すことができますが、これは廃止されたメソッドなので、まずdocsの潜在的な落とし穴を読んでください。それを無視して移動し続けるだけで、実行を継続することもできます。 –

+0

ありがとう、スレッドを停止する動作します。 – ihavprobs

0

接続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> 

これは私のためのタイムアウトの問題を固定設定します。

2

JavaのExecutorServiceインターフェイスを使用できます。以下は、あなたが何をする必要があるのか​​のサンプルです。

Future<Boolean> future = executor.submit(YOUR_METHOD); 
future.get(TIMEOUT_YOU_NEED, TimeUnit.SECONDS); 
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 ; 
      } 
      } 

そしてコール:私は、次の完全なクラスを作るためにCodeBoltとanpadiaで解答すると拡大

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

投稿者:[anonymous user](http://stackoverflow.com/review/suggested-edits/2889625): 'getConnection()メソッドを静的にすると、オブジェクトaを作成する必要はありません。中古。さらに、ドライバのクラス名、URL、ユーザー名、パスワードをgetConnection()の引数にして、かなり一般的な目的を持たせることができます。 – gunr2171

0

。タイムアウト期間を含む、必要なすべての接続パラメータを受け入れる静的メソッドは1つだけです。さらに、このメソッドは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); 
     } 
    } 
} 
関連する問題