【问题标题】:Java JDBC connection statusJava JDBC 连接状态
【发布时间】:2011-12-07 13:23:50
【问题描述】:

我正在(成功)使用以下方法连接到数据库:

java.sql.Connection connect = DriverManager.getConnection(
  "jdbc:mysql://localhost/some_database?user=some_user&password=some_password");

一段时间后,我应该检查什么以查看连接是否仍处于打开状态?
我希望有类似connect.isConnected(); 的东西可供我使用。

【问题讨论】:

    标签: java sql jdbc


    【解决方案1】:

    你也可以使用

    public boolean isDbConnected(Connection con) {
        try {
            return con != null && !con.isClosed();
        } catch (SQLException ignored) {}
    
        return false;
    }
    

    【讨论】:

    • 应该是 if(con!=null || !con.isClosed()) 以便您首先检查对象,如果它为 null 则不会继续验证 IF 语句.您的将引发异常,因为 con 可能为 NULL。那么你根本不需要整个 try catch。
    • 或者你可以直接return con != null && !con.isClosed()
    【解决方案2】:

    无论供应商实施如何,低成本的方法是从进程内存或服务器内存中选择一些东西,例如数据库版本或当前数据库的名称。 IsClosed 的实现非常糟糕。

    例子:

    java.sql.Connection conn = <connect procedure>;
    conn.close();
    try {
      conn.getMetaData();
    } catch (Exception e) {
      System.out.println("Connection is closed");
    }
    

    【讨论】:

      【解决方案3】:

      使用Connection.isClosed() 函数。

      JavaDoc 声明:

      检索此Connection 对象是否已关闭。一种 如果已在其上调用了 close 方法或 发生了某些致命错误。这种方法保证 只有在 Connection.close 方法之后调用它时才返回true 已被调用。

      【讨论】:

      • 正如 javadoc 所说,这 不会 在这种情况下给出有效的答案。它只会告诉close()是否被调用。
      • OK 在对 Postgres JDBC 驱动程序进行一些试验后(至少),基本上,如果底层连接“丢失”,isClosed() 仍将返回 true。但是,当您使用 连接并且它引发任何异常时,在那之后,isClosed() 现在将返回 true。所以基本上你可以“逃脱”使用isClosed(并避免额外调用isValid()的延迟),如果你能以某种方式在这里或那里承受中断的查询。除此之外,isValid() 是一种很好的测试方式,但需要额外的往返时间。
      • 不知道为什么这有赞成票,这部分 Javadoc 从答案中被省略了:This method generally cannot be called to determine whether a connection to a database is valid or invalid. A typical client can determine that a connection is invalid by catching any exceptions that might be thrown when an operation is attempted.
      【解决方案4】:

      什么都没有。只需执行您的查询。如果连接已断开,则您的 JDBC 驱动程序将重新连接(如果它支持它,并且您在连接字符串中启用了它 - 大多数不支持它),否则您将收到异常。

      如果您检查连接是否已建立,它可能会在您实际执行查询之前发生故障,因此您通过检查一无所获。

      也就是说,许多连接池通过在分发连接之前执行SELECT 1 之类的操作来验证连接。但这只不过是执行一个查询,所以您不妨执行您的业务查询。

      【讨论】:

      • 在使用它之前测试连接有一定的好处(特别是如果它是一个长期存在的连接并且底层网络可能已经使用它)。但这也是准确的,因为您仍然需要处理自己代码中的错误,因为它可能随时出现故障。
      【解决方案5】:

      你最好的机会是对一个表执行一个简单的查询,例如:

      select 1 from SOME_TABLE;
      

      哦,我刚刚看到从 1.6 开始有一个新方法可用:

      java.sql.Connection.isValid(int timeoutSeconds):

      如果连接尚未关闭并且仍然有效,则返回 true。 驱动程序应提交有关连接的查询或使用其他 积极验证连接的机制在以下情况下仍然有效 调用此方法。驱动程序提交的要验证的查询 连接应在当前上下文中执行 交易。

      【讨论】:

      • postgresql jdbc 执行"select 1",为记录。
      【解决方案6】:

      如果您使用的是 MySQL

      public static boolean isDbConnected() {
          final String CHECK_SQL_QUERY = "SELECT 1";
          boolean isConnected = false;
          try {
              final PreparedStatement statement = db.prepareStatement(CHECK_SQL_QUERY);
              isConnected = true;
          } catch (SQLException | NullPointerException e) {
              // handle SQL error here!
          }
          return isConnected;
      }
      

      我没有用其他数据库测试过。希望这会有所帮助。

      【讨论】:

      • db 来自哪里?
      • 在问题connect 变量中查看它是db 随便你命名。
      • 那么您可能需要关闭 PreparedStatement 以防止内存泄漏
      • @MonoThreaded,随心所欲,这只是示例。我不是在这里写真正的应用程序!
      • 如果你改为调用isValid(int timeoutSeconds) 方法,你基本上会得到这种行为,但会超时:)
      猜你喜欢
      • 2018-02-25
      • 1970-01-01
      • 2011-10-10
      • 1970-01-01
      • 1970-01-01
      • 2011-02-17
      • 2011-10-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多