Каков наилучший способ «пинговать» базу данных через JDBC? - PullRequest
12 голосов
/ 11 мая 2009

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

"SELECT 1 FROM DUAL"

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

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

Ответы [ 8 ]

13 голосов
/ 31 августа 2012

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

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

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

5 голосов
/ 11 мая 2009

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

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

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

4 голосов
/ 11 мая 2009

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

select 1 from SYSIBM.SYSDUMMY1;
3 голосов
/ 07 сентября 2011

Вы можете попытаться получить имя БД из метаданных соединения и выполнить соответствующее 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.
   ...
}
2 голосов
/ 02 мая 2014

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

"/* ping */ SELECT 1"

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

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

0 голосов
/ 11 мая 2009

Разве вы не можете просто выполнить

SELECT 1

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

0 голосов
/ 11 мая 2009

Достаточно просто выполнить следующий запрос

SELECT 1
0 голосов
/ 11 мая 2009

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

SELECT * FROM donkey_giraffe_87

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...