Есть ли безопасный способ узнать, поддерживает ли соединение JDBC?

У нас есть веб-сервер, обрабатывающий запросы от клиентов. Один компонент этого веб-сервера поддерживает соединение с базой данных.

Мне нужно уметь распознавать, было ли соединение закрыто или каким-то образом перестало функционировать, прежде чем я начну его использовать. В настоящее время я делаю что-то вроде:

// 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 ваше соединение, когда вы закончите с ним - пул перехватит закрытие и возвращает его в пул за кулисами.

Ответ 1

Лучший способ - сделать простой оператор SQL, такой как SELECT 1 или SELECT 1 FROM DUAL для Oracle. (Пожалуйста, см. Вашу базу данных для синтаксиса конкретного поставщика.)

Если это не удается, обновите соединение. То, что используют серверы приложений Java EE, такие как WebLogic, для их проверки, если вы настроили их для этого.

Ответ 2

Попробуйте

java.sql.Connection.isValid(int timeout) 

Возвращает true, если соединение не было закрыто и остается в силе.

Ответ 3

В каждой базе данных есть запрос, который не зависит от существующих таблиц. Для Oracle попробуйте

select 1 from dual

Для многих других баз данных (MySQL, H2) попробуйте

select 1

У DB2 есть свой уникальный синтаксис:

values 1

Ответ 4

В моем случае я использую 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;