【问题标题】:What is the best way to 'ping' a database via JDBC?通过 JDBC 'ping' 数据库的最佳方法是什么?
【发布时间】:2009-05-11 08:50:01
【问题描述】:

我正在尝试确定通过 JDBC ping 数据库的最佳方式。 “最佳”是指快速和低开销。例如,我考虑过执行这个:

"SELECT 1 FROM DUAL"

但我相信 DUAL 表是特定于 Oracle 的,我需要更通用的东西。

请注意,Connection 有一个 isClosed() 方法,但 javadoc 指出这不能用于测试连接的有效性。

【问题讨论】:

标签: java jdbc


【解决方案1】:

使用 JDBC 4,您可以从连接接口使用 isValid(int) (JavaDoc)。这基本上为你做了试用声明。

一些驱动程序通过向数据库发送正确的虚拟 SQL 来实现这一点,而一些驱动程序直接使用低级操作来减少解析开销。

但是要注意超时,一些驱动程序(DB/400 和 Oracle Thin)确实会为每次调用生成一个新的时间线程,这对于大多数池验证方案来说是不可接受的)。而且 Oracle 似乎也没有使用准备好的语句,所以它有点依赖隐式缓存。

【讨论】:

    【解决方案2】:

    是的,那将是仅 Oracle 的,但在 JDBC 中没有通用的方法来执行此操作。

    大多数连接池实现都有一个配置参数,您可以在其中指定将用于 ping 的 SQL,从而将责任推到用户身上。

    这似乎是最好的方法,除非有人为此想出了一个小辅助工具(当然,它排除了使用可能更快的非基于 SQL 的方法,如 Oracle's internal ping function

    【讨论】:

    • 看我的回答,JDBC 4 有一个通用的方式(因为并非所有驱动程序都提供 JDBC 4)。
    【解决方案3】:

    我也不知道通用解决方案。对于 IBM 在 iSeries(可能还有其他 DB2 系统)上的 UDB,它会是

    select 1 from SYSIBM.SYSDUMMY1;
    

    【讨论】:

    【解决方案4】:

    MySQL 有一个很好的机制,记录在SO answer 中。来自答案:

    "/* ping */ SELECT 1"
    

    这实际上会导致驱动程序向服务器发送 ping 并返回一个假的、轻量级的结果集。

    话虽如此,@eckes answer 是最好的(使用 JDBC 4 的 Connection.isValid(int))。

    【讨论】:

      【解决方案5】:

      您可以尝试从连接元数据中获取数据库名称并执行匹配的 sql 语句。例如

      Connection con = null;
      Statement st = null;
      ResultSet rs = null;
      try {
        con = dataSource.getConnection();
        String dbProductName = con.getMetaData().getDatabaseProductName();
        Statement st = con.createStatement();
        if ( "PostgreSQL".equalsIgnoreCase(dbProductName) ) {
          rs = st.executeQuery("select version();");
        } else if ( "Oracle".equalsIgnoreCase(dbProductName) ) {
          rs = st.executeQuery("select 1 from dual");
        } else {
         ...
        }
      } catch ( Exception ex ) {
        System.out.prinln("DB not reachable");
      } finally {
         // close statement, connection etc.
         ...
      }
      

      【讨论】:

        【解决方案6】:

        我可能会出去吃午饭,但你能简单地执行一些无意义的查询吗,例如:

        SELECT * FROM donkey_giraffe_87
        

        我不太了解 JDBC 的错误处理,但也许您可以检查一下数据库是否至少告诉您该表不存在。如果 JDBC 的错误代码是特定于供应商的,那么 Spring 框架有一些实用程序可以将这些代码映射到更有意义的异常。

        【讨论】:

        • 尝试查询不存在的表可能会很昂贵。字典缓存未命中和错误处理代码。
        【解决方案7】:

        只需发出以下查询就足够了

        SELECT 1
        

        【讨论】:

        • ORA-00923: FROM 关键字未在预期位置找到
        • 这是 postgres 特有的
        猜你喜欢
        • 2018-09-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-05
        • 1970-01-01
        • 1970-01-01
        • 2012-05-26
        • 1970-01-01
        相关资源
        最近更新 更多