Есть ли способ восстановить соединение JBoss с Oracle в случае сбоя соединения?
У нас есть наши JBoss и Oracle на отдельных серверах. Кажется, что соединения разорваны и вызывают проблемы с JBoss. Как я могу повторно подключить JBoss к Oracle, если соединение плохое, пока мы выясняем, почему соединения в первую очередь сбрасываются?
6 ответов
Обычно в пуле есть параметр конфигурации, позволяющий выполнить запрос проверки при заимствовании. Если запрос проверки выполняется успешно, пул вернет это соединение. Если запрос не выполняется успешно, пул создаст новое соединение.
JBoss Wiki документирует различные атрибуты пула.
<check-valid-connection-sql>select 1 from dual</check-valid-connection-sql>
Похоже, это должно сработать.
Хотя вы можете использовать старый трюк "выбрать 1 из двойного", недостатком этого является то, что он выдает дополнительный запрос каждый раз, когда вы заимствуете соединение из пула. Для больших объемов это расточительно.
JBoss предоставляет специальный валидатор соединения, который следует использовать для Oracle:
<valid-connection-checker-class-name>
org.jboss.resource.adapter.jdbc.vendor.OracleValidConnectionChecker
</valid-connection-checker-class-name>
При этом используется собственный метод ping() класса Oracle JDBC Connection и используется сетевой код драйвера, чтобы определить, живо ли соединение.
Тем не менее, запускать его каждый раз при заимствовании соединения по-прежнему бесполезно, поэтому вы можете использовать средство, где фоновый поток проверяет соединения в пуле и молча отбрасывает мертвые. Это намного более эффективно, но означает, что если соединения не работают, любая попытка использовать их до запуска фонового потока провалится.
См. Вики документы о том, как настроить проверку фона (ищите background-validation-millis
).
Недостаточно репутации для комментария, поэтому он находится в форме ответа. 'Select 1 from dual'
и скаффмана org.jboss.resource.adapter.jdbc.vendor.OracleValidConnectionChecker
Метод эквивалентен, хотя проверка соединения обеспечивает уровень абстракции. Нам пришлось декомпилировать драйверы oracle jdbc для устранения неполадок, а внутренняя реализация ping в Oracle - выполнить 'Select 'x' from dual'
, Спичечный.
JBoss предоставляет 2 способа проверки соединения: - на основе пинга и - на основе запроса
Вы можете использовать согласно требованию. Это запланировано отдельным потоком согласно продолжительности, определенной в файле конфигурации источника данных.
<background-validation>true</background-validation> <background-validation-minutes>1</background-validation-minutes>
Некоторое время, если у вас нет правильного драйвера оракула в Jboss, вы можете получить classcast или связанную ошибку, и для этого соединения может начаться выпадение из пула соединений. Вы можете попробовать создать свой собственный класс ConnectionValidator, реализовав org.jboss.resource.adapter.jdbc.ValidConnectionChecker
интерфейс. Этот интерфейс обеспечивает только один методisValidConnection()
и ожидая 'NULL' в обмен на действительное соединение.
Пример:
public class OracleValidConnectionChecker implements ValidConnectionChecker, Serializable {
private Method ping;
// The timeout (apparently the timeout is ignored?)
private static Object[] params = new Object[] { new Integer(5000) };
public SQLException isValidConnection(Connection c) {
try {
Integer status = (Integer) ping.invoke(c, params);
if (status.intValue() < 0) {
return new SQLException("pingDatabase failed status=" + status);
}
}
catch (Exception e) {
log.warn("Unexpected error in pingDatabase", e);
}
// OK
return null;
}
}
Недавно у нас были некоторые плавающие ошибки обработки запросов, вызванные осиротевшим оракулом DBMS_LOCK
блокировки сеансов, которые сохраняются неопределенно долго в пуле соединений на стороне клиента.
Итак, вот решение, которое принудительно истекает через 30 минут, но не влияет на работу приложения:
<check-valid-connection-sql>select case when 30/60/24 > sysdate-LOGON_TIME then 1 else 1/0 end
from V$SESSION where AUDSID = userenv('SESSIONID')</check-valid-connection-sql>
Это может привести к некоторому замедлению процесса получения соединений из пула. Не забудьте проверить это под нагрузкой.
Небольшое обновление к ответу @skaffman. В JBoss 7 вы должны использовать атрибут "class-name" при установке правильной проверки соединения, а также пакет отличается:
<valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.oracle.OracleValidConnectionChecker" />