12

我们有一个网络服务器处理来自客户的请求。此 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 小时空闲后。

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

我不介意对它运行一个非常小的查询,但它必须与数据库无关,并且几乎不需要时间/资源。

顺便说一句:我在 Java 5 下运行,所以Connection.isValid对我来说不是解决方案。


添加

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

唯一奇怪的部分是意识到使用连接池close时,您必须在完成连接后进行连接 - 池拦截关闭并将其返回到幕后的池中。

4

4 回答 4

13

SELECT 1最好的方法是SELECT 1 FROM DUAL为 Oracle 做一个简单的 SQL 语句。(有关特定于供应商的语法,请参阅您的数据库。)

如果失败,请刷新连接。这就是像 WebLogic 这样的 Java EE 应用服务器所做的测试,如果您将它们配置为这样做的话。

于 2013-01-14T14:24:03.047 回答
10

尝试

java.sql.Connection.isValid(int timeout) 

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

于 2013-01-14T14:25:09.440 回答
4

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

select 1 from dual

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

select 1

DB2 有它自己独特的语法:

values 1
于 2013-01-14T14:25:40.863 回答
1

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

我有一个方法 getConnection (或在这个例子中 getInstance no poll):

try {
    if (connect == null) || ! connect.isValid() ) {
        connect.DriverManager.getConnection(...);
} catch (SQLException e) {
    logger.error(...);
    connect = null;
}
return connect;
于 2015-04-10T10:50:31.050 回答