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

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

посмотреть wiki docs для как настроить проверку фона (ищите background-validation-millis).


недостаточно репутации для комментария, поэтому это в форме ответа. The 'Select 1 from dual' и skaffman это org.jboss.resource.adapter.jdbc.vendor.OracleValidConnectionChecker метод эквивалентен, хотя проверка соединения обеспечивает уровень абстракции. Нам пришлось декомпилировать драйверы oracle jdbc для устранения неполадок, и внутренняя реализация Oracle ping должна выполнить 'Select 'x' from dual'. Естественно.


JBoss предоставляет 2 способа проверки соединения: - Ping на основе и - Запрос

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

<background-validation>true</background-validation> <background-validation-minutes>1</background-validation-minutes>

некоторое время, если у вас нет правильного драйвера oracle в Jboss, вы можете получить classcast или связанную ошибку, и для этого соединения может начаться отсев из пула соединений. Вы можете попробовать создать свой собственный класс ConnectionValidator, реализуя org.jboss.resource.adapter.jdbc.ValidConnectionChecker интерфейс. Этот интерфейс предоставляет только один метод'isValidConnection() 'и ожидание" NULL " в обмен на действительное соединение.

Ex:

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

недавно у нас были некоторые сбои обработки плавающих запросов, вызванные осиротевшим oracle 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" />