Есть ли какой-нибудь способ повторно подключить пул соединений JBoss к Oracle в случае сбоя соединений? - PullRequest
30 голосов
/ 24 сентября 2008

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

Ответы [ 6 ]

32 голосов
/ 28 сентября 2008

Хотя вы можете использовать старый трюк «выбрать 1 из двойного», недостатком этого является то, что он выдает дополнительный запрос каждый раз, когда вы заимствуете соединение из пула. Для больших объемов это расточительно.

JBoss предоставляет специальный валидатор соединения, который следует использовать для Oracle:

<valid-connection-checker-class-name>
    org.jboss.resource.adapter.jdbc.vendor.OracleValidConnectionChecker
</valid-connection-checker-class-name>

Это использует собственный метод ping () класса Oracle JDBC Connection и использует базовый сетевой код драйвера, чтобы определить, живо ли еще соединение.

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

См. вики-документы , чтобы узнать, как настроить проверку фона (ищите background-validation-millis).

26 голосов
/ 24 сентября 2008

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

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

<check-valid-connection-sql>select 1 from dual</check-valid-connection-sql>

Кажется, это должно сработать.

9 голосов
/ 20 июня 2014

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

6 голосов
/ 23 июня 2012

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 в обмен на действительное соединение.

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;
   }
}
3 голосов
/ 29 сентября 2015

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

Это может привести к некоторому замедлению процесса получения соединений из пула. Обязательно проверьте это под нагрузкой.

2 голосов
/ 08 декабря 2014

Небольшое обновление к ответу @ skaffman. В JBoss 7 вы должны использовать атрибут "class-name" при установке правильной проверки соединения, а также пакет отличается:

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

...