Posiadamy nasze JBoss i Oracle na oddzielnych serwerach. Połączenia wydają się być opuszczone i powoduje problemy z JBoss. Jak mogę połączyć się z JBoss do Oracle, jeśli połączenie jest złe, a my ustalamy, dlaczego połączenia są usuwane w pierwszej kolejności?Czy jest jakiś sposób, aby pula połączeń JBoss ponownie nawiązała połączenie z bazą danych Oracle, gdy połączenia się zepsują?
Odpowiedz
Zazwyczaj w puli jest opcja konfiguracji, która umożliwia wykonanie kwerendy sprawdzania poprawności przy pożyczaniu. Jeśli kwerenda sprawdzania poprawności zostanie wykonana pomyślnie, pula zwróci to połączenie. Jeśli zapytanie nie zostanie wykonane pomyślnie, pula utworzy nowe połączenie.
Dokumenty JBoss Wiki przedstawiają różne atrybuty puli.
<check-valid-connection-sql>select 1 from dual</check-valid-connection-sql>
Wygląda na to, że powinno wystarczyć.
Chociaż można użyć starej sztuczki "wybierz 1 z podwójnej", wadą tego jest to, że za każdym razem, gdy pożyczasz połączenie z puli, wydaje dodatkowe zapytanie. W przypadku dużych woluminów jest to marnotrawstwem.
JBoss zapewnia specjalny walidator połączenia, które powinny być wykorzystywane do Oracle:
<valid-connection-checker-class-name>
org.jboss.resource.adapter.jdbc.vendor.OracleValidConnectionChecker
</valid-connection-checker-class-name>
To sprawia, że stosowanie metody zastrzeżone ping() na klasy Connection Oracle JDBC i wykorzystuje podstawowy kod sieci operatora w celu określenia jeśli połączenie jest nadal żywe.
Jednak nadal nie można uruchomić tego za każdym razem, gdy połączenie jest pożyczone, więc możesz chcieć użyć obiektu, w którym wątek w tle sprawdza połączenia w puli i cicho odrzuca te martwe. Jest to o wiele bardziej wydajne, ale oznacza, że jeśli połączenia przestaną być wykonywane, każda próba użycia ich przed uruchomieniem wątku tła zakończy się niepowodzeniem.
Zobacz, jak skonfigurować sprawdzanie w tle (patrz:).
Metoda "Wybierz 1 z podwójnej" i org.jboss.resource.adapter.jdbc.vendor.OracleValidConnectionChecker są równoważne, chociaż sprawdzanie połączenia zapewnia poziom abstrakcji. Musieliśmy zdekompilować sterowniki jdbc do rozwiązywania problemów, a wewnętrzna implementacja polecenia ping używanego przez Oracle podczas sprawdzania połączenia polega na wykonaniu "Wybierz" x "z podwójnego". Natch. – abh
Należy zauważyć, że 'OracleValidConnectionChecker' miał [mniejszy błąd] (https://bugzilla.redhat.com/show_bug.cgi?id=699816) w JBoss AS 4 i 5. Pamiętam również, że miał problemy z wydajnością w ciężkim równoczesnym obciążeniu dzięki zastosowaniu osobnej nitki pingerowej pod maską. – Vadzim
JBoss oferuje 2 sposoby, aby sprawdzić poprawność połączenia: - Ping opartych I - Zapytanie oparte
można wykorzystywać zgodnie z wymogiem. Jest to zaplanowane przez osobny wątek zgodnie z czasem trwania zdefiniowanym w pliku konfiguracyjnym źródła danych.
<background-validation>true</background-validation> <background-validation-minutes>1</background-validation-minutes>
jakiś czas, jeśli nie mają odpowiedniego sterownika wyroczni w Jboss, można uzyskać classcast lub powiązanego błędu iz tego związku może rozpocząć porzucaniu z puli połączeń. Możesz spróbować utworzyć własną klasę ConnectionValidator, implementując interfejs org.jboss.resource.adapter.jdbc.ValidConnectionChecker
. Ten interfejs zapewnia tylko jedną metodę "isValidConnection()
" i oczekuje "NULL" w zamian za prawidłowe połączenie.
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;
}
}
mało rep o komentarz, więc jest to w formie odpowiedzi. Metoda 'Select 1 from dual'
i skaffmanna org.jboss.resource.adapter.jdbc.vendor.OracleValidConnectionChecker
są równoważne, chociaż sprawdzanie połączenia zapewnia poziom abstrakcji. Musieliśmy zdekompilować sterowniki jdbc Oracle do rozwiązywania problemów, a wewnętrzna implementacja ping Oracle'a polega na wykonaniu 'Select 'x' from dual'
. Natch.
Mała aktualizacja odpowiedzi @ skaffmana. W JBoss 7 trzeba użyć „class-name” atrybut przy tworzeniu prawidłowych sprawdzania połączenia, a także pakiet jest inny:
<valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.oracle.OracleValidConnectionChecker" />
Niedawno miał jakieś błędy obsługi pływających żądania spowodowane osieroconych oracle DBMS_LOCK
zamków sesyjnych utrzymywane w nieskończoność w puli połączeń po stronie klienta.
Więc tutaj jest rozwiązanie, które zmusza sesji upływie 30 minut, ale nie wpływa na działanie aplikacji:
<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>
ta może obejmować pewne spowolnienie procesu uzyskiwania połączeń z basenu. Sprawdź to pod obciążeniem.
Bardzo ładna sztuczka. –
Dude to jest takie proste. –
Co to znaczy 30/60/24? –
Jeśli masz już ten wiersz w swoim dokumencie cfg, sprawdź także, czy nie ustawiono wartości "validate-on-match" i "background-validation" na wartość "false" (więcej informacji na temat połączonej strony wiki). – Pino