2013-01-14 5 views
10

У нас есть веб-сервер, обрабатывающий запросы от клиентов. Один компонент этого веб-сервера поддерживает соединение с базой данных.Есть ли безопасный способ узнать, поддерживает ли соединение 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 не является для меня решением.


Добавлено

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

Единственная странная часть - это осознание того, что с пулом подключений вы должны подключиться, когда вы закончите с ним - пул перехватит закрытие и возвращает его в пул за кулисами.

+1

Что у вас есть против готовых пулов соединений, которые проверяют соединения как обычные? –

+0

@MarkoTopolnik - ничего - как такового - но я подготовил заявления, прикрепленные к этим соединениям, поэтому я должен сам справиться с ними. Или я? – OldCurmudgeon

+1

На самом деле, это опасение, что эти пулы также обрабатываются с помощью подготовленных пулов инструкций. BTW мой выбор будет * boneCP *. –

ответ

11

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

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

+0

Я думаю, было бы целесообразно, если бы вы подчеркнули тот факт (который, как кажется, немного подразумевается в вашем ответе), что некоторые серверы приложений уже выполняют эту проверку автоматически (если вы настроили их для этого). Например, в WebSphere. – Isaac

+0

Выполнено - спасибо. – duffymo

+0

Будет ли 'SELECT 1' работать со всеми базами данных? – OldCurmudgeon

8

Попробуйте

java.sql.Connection.isValid(int timeout) 

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

+0

Извините, я должен был удержаться. Я бегу под Java 5. – OldCurmudgeon

+0

Просто добавленный бит информации, насколько мне известно, метод 'java.sql.Connection.isValid (int timeout)' вызывает SELECT 1' – JackB

4

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

select 1 from dual 

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

select 1 

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

values 1 
+0

"значения 1 «? Это не какой-то SQL, который я узнаю ... – duffymo

+1

DB2 использует этот синтаксис для создания ad-hoc-таблиц из списка значений. Найдите документацию для оператора VALUES. –

+0

Спасибо, но я не использую DB2 (слава богу). – duffymo

0

Im мой случай, я использую 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; 
+0

Это, безусловно, стоит того, чтобы иметь это решение в качестве опции, но помните, что 'isValid' доступен только в Java 1.6 и далее. В целом - мой совет: * зайти в пул соединений *. – OldCurmudgeon

Смежные вопросы