Jak skomentowałem wcześniej, dzieje się tak dlatego, że gniazda, które są otwarte i połączone z bazą danych, nie zdają sobie sprawy, że połączenie zostało utracone, więc pozostawały połączone do momentu wyzwolenia limitu czasu gniazda systemu operacyjnego, co może trwać zwykle około 30 minut .
Aby rozwiązać ten problem, musisz zastąpić limit czasu gniazda w ciągu połączenia JDBC lub w konfiguracji/właściwościach połączenia JDNI, aby zdefiniować socketTimeout param do mniejszego czasu.
Pamiętaj, że każde połączenie dłuższe niż zdefiniowana wartość zostanie zabite, nawet jeśli jest używane (nie byłem w stanie tego potwierdzić, przeczytałem).
Pozostałe dwa parametry, o których wspominam w moim komentarzu, to connectTimeout i automatyczne ponowne połączenie .
Oto moje parametry połączenia JDBC:
jdbc:(...)&connectTimeout=15000&socketTimeout=60000&autoReconnect=true
Wyłączyłem również pamięć podręczną DNS Javy, wykonując
java.security.Security.setProperty("networkaddress.cache.ttl" , "0");
java.security.Security.setProperty("networkaddress.cache.negative.ttl" , "0");
Robię to, ponieważ Java nie honoruje TTL, a kiedy następuje przełączenie awaryjne, DNS jest taki sam, ale zmienia się adres IP.
Ponieważ używasz serwera aplikacji, parametry wyłączające pamięć podręczną DNS muszą zostać przekazane do JVM podczas uruchamiania glassfisha za pomocą -Dnet, a nie samej aplikacji.