Подтвердить что ты не робот

Каков наилучший способ "ping" базы данных через JDBC?

Я пытаюсь определить лучший способ для ping базы данных через JDBC. "Лучшим" я имею в виду быстрые и низкие накладные расходы. Например, я рассмотрел выполнение этого:

"SELECT 1 FROM DUAL"

но я считаю, что таблица DUAL является специфичной для Oracle, и мне нужно что-то более общее.

Обратите внимание, что Connection имеет метод isClosed(), но javadoc заявляет, что это не может использоваться для проверки правильности подключения.

4b9b3361

Ответ 1

Да, это будет только Oracle, но в JDBC нет общего способа сделать это.

В большинстве реализаций пула соединений есть параметр конфигурации, где вы можете указать SQL, который будет использоваться для ping, тем самым повысив ответственность за то, как это сделать для пользователя.

Это похоже на лучший подход, если кто-то не придумает для этого небольшой вспомогательный инструмент (конечно, он не позволяет использовать потенциально даже более быстрые не-SQL-методы, такие как Внутренняя функция пинга Oracle)

Ответ 2

В JDBC 4 вы можете использовать isValid(int) (JavaDoc) из интерфейса подключения. Это в основном делает пробное выражение для вас.

Однако остерегаясь тайм-аута, некоторые драйверы (DB/400 и Oracle Thin) порождают новый поток времени для каждого вызова, что не совсем приемлемо для большинства сценариев проверки пула)

Ответ 3

Я также не знаю об общем решении. Для IBM UDB на iSeries (и, возможно, в других системах DB2) это будет

select 1 from SYSIBM.SYSDUMMY1;

Ответ 4

Вы можете попытаться получить имя db из метаданных соединения и выполнить соответствующий 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.
   ...
}

Ответ 5

Я могу пообедать на этом, но вы могли бы просто выполнить какой-то неинтересный запрос, например:

SELECT * FROM donkey_giraffe_87

Я не очень разбираюсь в обработке ошибок JDBC, но, возможно, вы можете проверить, не указывает ли база данных, что таблица не существует. Если коды ошибок JDBC специфичны для поставщиков, Spring Framework имеет некоторые утилиты для сопоставления этих кодов более значимым исключениям.

Ответ 6

MySQL имеет хороший механизм, описанный в этом SO-ответе. Из ответа:

"/* ping */ SELECT 1"

Это приведет к тому, что драйвер отправит пинг на сервер и вернет фальшивый, легкий результат.

Сказав, что @eckes answer является лучшим (с использованием JDBC 4 Connection.isValid(int)).

Ответ 7

Простое выполнение следующего запроса должно быть достаточным

SELECT 1

Ответ 8

Не можете ли вы просто выполнить

SELECT 1

без предложения FROM для большинства баз данных?