有没有一种安全的方法来判断JDBC连接是否仍然正常?

时间:2013-01-14 14:22:34

标签: java jdbc connection connection-pooling

我们有一个Web服务器处理来自客户端的请求。此Web服务器的一个组件包含与数据库的连接。

在我开始使用之前,我需要能够识别连接是否已关闭或在某种程度上不再起作用。目前我做的事情如下:

// Decide connection details on alias.
private String alias = null;
// I must have my own because I prepare statements.
private Connection connection = null;

public Connection getConnection() {
  try {
    if ( connection.isClosed() ) {
      // Start afresh.
      connection = null;
    }
    // ** More tests here to check connection is ok.
    if (connection == null) {
      // Make a new connection.
      connection = Connections.getConnection(alias);
    }
  } catch (SQLException ex) {
    // Cause a NPE further down the line.
    connection = null;
  }
  return connection;
}

可悲的是,这有时会返回如此陈旧的连接,我会收到各种错误之一。其中一个看起来像:

  

java.sql.SQLException:Io异常:软件导致连接中止:套接字写入错误

请注意,这只是记录的错误之一,这个错误在大约72小时闲置后发生。

我正在寻找的是一个连接的最小数据库通用测试程序,它应该始终如一地判断连接是否已启动,运行且稳定。这可能吗?

我不介意针对它运行一个非常小的查询,但它必须是数据库不可知的并且几乎没有时间/资源。

BTW:我在Java 5下运行,因此Connection.isValid对我来说不是解决方案。


对于那些稍后访问此问题的人 - 我最终接受了所提供的建议并转移到了一个真正的连接池,不仅非常容易做到,而且所有的问题都消失了。

唯一奇怪的部分是认识到连接池在完成连接时必须close你的连接 - 池拦截关闭并将其返回到幕后的池中。

4 个答案:

答案 0 :(得分:12)

最好的方法是为Oracle执行简单的SQL语句,如SELECT 1SELECT 1 FROM DUAL。 (请参阅您的数据库以获取特定于供应商的语法。)

如果失败,请刷新连接。这就是像WebLogic这样的Java EE应用程序服务器在配置它们时如何测试它们。

答案 1 :(得分:10)

尝试

java.sql.Connection.isValid(int timeout) 

如果连接尚未关闭且仍然有效,则返回true。

答案 2 :(得分:4)

每个数据库都有一个不依赖于现有表的查询。对于Oracle,请尝试

select 1 from dual

对于许多其他数据库(MySQL,H2),请尝试

select 1

DB2拥有自己独特的语法:

values 1

答案 3 :(得分:1)

我的情况,我使用java.sql.Connection.isValid(int timeout):

我有一个方法getConnection(或者getInstance在这个例子中没有轮询):

try {
    if (connect == null) || ! connect.isValid() ) {
        connect.DriverManager.getConnection(...);
} catch (SQLException e) {
    logger.error(...);
    connect = null;
}
return connect;