如何在执行Statement.executeQuery()时处理Java冻结?

时间:2013-01-07 17:57:30

标签: java mysql jdbc

您好我正在编写一个在Java中运行的应用程序,并通过JDBC与MySQL数据库进行对话。我遇到的问题是这个应用程序是一个实时应用程序,并且在某些时候与数据库的连接是不可避免的。这是代码草图:

int result          = 0;
Statement st        = null;
ResultSet rs        = null;
System.out.println("Obatining reference to main connection");
Connection conne    = Main.connection;
try {
    System.out.println("In try");
    System.out.println("Creating statement");
    st = conne.createStatement();
    System.out.println("Obtaining result");
    rs = st.executeQuery("Properly constructed and tested sql query");
    rs.last();
    result = rs.getRow();
    System.out.println("Exiting try");
}catch(SQLException se){ 
    se.printStackTrace();
}finally{
    System.out.println("In finally");
    try { rs.close();    } catch (Exception e) { /* ignored */ }
    try { st.close();    } catch (Exception e) { /* ignored */ }
}
  return result;

程序在打印获取结果后冻结。如果连接处于活动状态,则一切运行正常,但我需要保护它免受数据库故障的影响。我测试它的方法是在运行此方法之前断开与数据库的连接。没有抛出异常,也没有生成错误。一旦打印获得结果,程序就会挂起。我希望有人知道从这种情况中恢复的方法吗?应用程序再次运行完美,但我需要能够从数据库中恢复不可用。

更多信息:

断开连接是指我通过vpn连接到数据库并关闭vpn以使数据库不可用。

有人发布SQL没有正确格式化。请允许我澄清一下,这不是实际的SQL语句。我宁愿不把实际的陈述放进去,它实际上并不相关,因为任何有效的陈述都会产生相同的不良影响。

2 个答案:

答案 0 :(得分:0)

一种选择是在后台线程上进行数据库工作。这使得可以等待指定的时间,然后在时间到期时继续。

最简单的入门方式是使用ExecutorService。您可以提交单个任务,并等待返回的Future一段特定时间。另请查看invokeAll方法和朋友。

您也可以尝试使用statement timeout,但如果存在驱动程序错误或意外通信问题(例如,查询执行速度快但需要很长时间才能传输),则可能不如Executor方法可靠结果)。

答案 1 :(得分:0)

这是桌面应用程序还是Java EE应用程序?

如果它是桌面应用程序,您可以尝试将数据库交互作为一个线程,并为它们设置超时。

如果它是Java EE应用程序,并且您不愿意使用任何框架,您可以查看一些事务库,并实现对内部事务的显式控制(例如向它们添加超时)。起点:http://docstore.mik.ua/orelly/java-ent/ebeans/ch08_05.htm