JDBC Microsoft SQL超时未触发

时间:2016-02-16 18:03:12

标签: java sql-server jdbc

我使用sqljdbc4.jar通过wifi从我的应用程序连接到SQL Server。连接工作正常并且查询也是如此,但有时wifi会掉线而我需要做出反应 - 尝试重新连接,然后通知用户连接失败。

问题是,即使我设置了查询超时,执行也会在断开连接时挂起,并且不会触发SqlTimeoutException

连接(用户名和psw已删除):

SQLconnection = DriverManager.getConnection("jdbc:sqlserver://%address%;user=%UserName%;password=%password%;database=%db_name%");

SQLSelectStatement = SQLconnection.createStatement();
SQLSelectStatement.setQueryTimeout(2);

执行查询:

String sql = "%my query%";
ResultSet rs;
try {
    rs = SQLSelectStatement.executeQuery(sql);
} catch (SQLException sqle) {
    ConnectSQL(); //try to connect again
    rs = SQLSelectStatement.executeQuery(sql);
}

如果方法抛出SQLException,我会通知用户并继续。但是,即使在连接丢失的情况下,也不会抛出异常。

我该怎么做才能解决这个问题?我尝试在基于MSDN的连接字符串中设置lock-timeout和logintimeout,方法SQLconnection.setNetworkTimeout也会触发错误(如果我理解正确,则不会在microsoft驱动程序中实现)。

我能想到的最后一个解决方案是自己实现某种超时,这将在一段时间后停止查询线程。但我不会重新发明轮子。

2 个答案:

答案 0 :(得分:4)

基于我的谷歌搜索和阅读,setQueryTimeout仅用于限制查询执行时间,而不用于检测连接错误。

我发现this great article描述了JDBC驱动程序中的超时。我只需要点击MS {0}中不支持的socketTimeout

我切换到jTDS driver并重新编写了我的代码。现在它按预期工作。

//initialize SQL connection
    try {
        Class.forName("net.sourceforge.jtds.jdbc.Driver");
    } catch (ClassNotFoundException ex) {
        Cls_log.LogError(ex);
    }

private void ConnectSQL() {
    try {
        String url = "jdbc:jtds:sqlserver://<ip_address>/<db_name>;instance=<SQLserver_name>;loginTimeout=5;socketTimeout=2";
        SQLconnection = DriverManager.getConnection(url, <userName>, <password>);
        SQLSelectStatement = SQLconnection.createStatement();
    } catch (SQLException ex) {
        Cls_log.LogError(ex);
    }
}

执行我的查询

String sql = "%my query%";
ResultSet rs;
try {
    rs = SQLSelectStatement.executeQuery(sql);
} catch (SQLException sqle) {
    ConnectSQL(); //try to connect again
    rs = SQLSelectStatement.executeQuery(sql);
}

如果抛出SQLException,我会通知用户并提供解决方法。

答案 1 :(得分:1)

此外,最近的Microsoft驱动程序也支持它:https://github.com/Microsoft/mssql-jdbc/pull/85/files