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

StackOverflow https://stackoverflow.com/questions/128527

Вопрос

У нас есть JBoss и Oracle на разных серверах.Кажется, что соединения прерваны, что вызывает проблемы с JBoss.Как я могу заставить JBoss повторно подключиться к Oracle, если соединение плохое, пока мы выясняем, почему соединения вообще разрываются?

Это было полезно?

Решение

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

А JBoss вики документирует различные атрибуты пула.

<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>

Иногда, если у вас нет подходящего драйвера Oracle в Jboss, вы можете получить ошибку приведения классов или связанную с ней ошибку, и для этого соединения может начаться исключение из пула соединений.Вы можете попробовать создать свой собственный класс 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 вам необходимо использовать атрибут «имя класса» при настройке допустимой проверки соединения, а также пакет отличается:

<valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.oracle.OracleValidConnectionChecker" />

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top