2012-01-30 10 views
5

ja dostaję strasznych MySQL JDBC wyjątków połączenia nieświeże:połączenia Nieświeży, validationQuery nie rozwiąże

Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed. 
Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was 243,263,541 milliseconds ago. The last packet sent successfully to the server was 243,263,541 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem. 

Wydaje się, że wszyscy zgadzają się, że ta jest ustalona za pomocą validationQuery + testOnBorrow, ale to nie jest rozwiązanie problemu .

Używam następujące oprogramowanie MySQL 5.1.41-3ubuntu12.10 Connector/J 5.1.18 Tomcat 6.0.24

Oto jak połączenie jest zdefiniowana w server.xml, używamy tomcat-dbcp, aby połączyć połączenia.

<Resource 
     auth="Container" 
     driverClassName="com.mysql.jdbc.Driver" 
     factory="org.apache.commons.dbcp.BasicDataSourceFactory" 
     logAbandoned="true" 
     maxActive="75" 
     maxIdle="20" 
     maxWait="10000" 
     name="jdbc/jndiname" 
     password="password" 
     removeAbandoned="true" 
     removeAbandonedTimeout="60" 
     validationQuery="/* ping */SELECT 1" 
     testOnBorrow="true" 
     testOnReturn="true" 
     timeBetweenEvictionRunsMillis="10000" 
     testWhileIdle="true" 
     scope="Shareable" 
     type="javax.sql.DataSource" 
     url="jdbc:mysql://host:3306/schema" 
     username="username" /> 
+0

W jakiej sytuacji uzyskujesz te nieaktualne wyjątki połączenia? Czy wysyłasz zapytanie na żywo i to jest wynik? Czy po prostu utworzyłeś połączenie JDBC, tak jak to zrobiłeś, lub czy pobierasz je z puli połączeń? – technocrat

+0

Wyjątki połączenia występują każdego ranka, gdy użytkownik łączy się z naszą aplikacją internetową po raz pierwszy. Połączenia pochodzą z puli Tomcat-DBCP. Możemy rozwiązać ten problem, restartując Tomcat każdego dnia, ale to tylko maskowanie prawdziwego problemu. – user763648

+0

Po ponownym uruchomieniu Tomcat wszystko co robisz, powoduje, że sama pula połączeń sama się z powrotem tworzy. Czy uważasz, że poprawką do tego będzie konfiguracja tomcat, konfiguracja mysql lub zmiana kodu pool tomcat-dbcp? .. Tak więc wiem, w którym kierunku szukać odpowiedzi. – technocrat

Odpowiedz

0

Mogę sprawdzić wait_timeout w pliku my.cnf. Wartość domyślna to 28800 sekund lub 8 godzin. Ma maksymalnie 31536000 sekund lub 365 dni.

Dla pierwszego wyjątku należy pamiętać: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException, W przeszłości zawijałem to w bloku try/catch. W haczyku, dla tego wyjątku, miałem połączenie ponownie, a następnie ponownie wysłałem zapytanie. Wiedząc, że nie chciałem tego robić bardzo często i nadal utrzymuję otwarte połączenie, zwiększyłem również domyślny czas oczekiwania na coś sensownego dla mojej aplikacji.

Patrz instrukcja referencyjna: http://dev.mysql.com/doc/refman/5.6/en/server-system-variables.html#sysvar_wait_timeout

+1

Nasz wait_timeout jest ustawiony na domyślne 28800 sekund, ale wolimy ustalić przyczynę problemu, niż tylko zmniejszyć częstotliwość. – user763648

+0

To przynajmniej da ci trochę pokoju oddechowego, dopóki go nie naprawisz. Co mówi ta wartość: Jeśli moje połączenie nie będzie używane przez 28800 sekund, zakończ je! W twoim systemie, jeśli twoja pula Tomcat-DBCP nie utrzyma jej aktywnego połączenia (jak w instrukcji DDL lub DML/query/insert/select ..) to MySQL zakończy połączenie po 8 godzinach, może nie zdajesz sobie z tego sprawy jeszcze dopóki nie spróbujesz wykonać wspomnianego DDL/DML. Czy możesz opublikować kod, w którym konfigurujesz pulę połączeń? Podobny problem na MySQL: http://forums.mysql.com/read.php?39,501441,501692#msg-501692 – technocrat

+0

Mam zaktualizowane pytanie, aby dołączyć nasz pełny atrybut połączenia z server.xml. Cała nasza logika bazy danych jest inicjowana z warstwy Hibernate, przez tomcat-dbcp do sterownika Connector/J. – user763648

0

zapytanie walidacji jest nieprawidłowy. Usuń "wybierz 1" i pozostaw tylko ping.

+0

Nieprawdziwe, patrz http://dev.mysql.com/doc/connector-j/en/connector-j-usagenotes-j2ee-concepts-connection-pooling.html Aby użyć tej funkcji, należy określić zapytanie weryfikacji w twoja pula połączeń zaczynająca się od/* ping */ 'chroniona statyczna końcowa String PING_MARKER ="/* ping */";' '...' 'if (sql.charAt (0) == '/') {' ' if (sql.startsWith (PING_MARKER)) {' ' doPingInstead(); ' '} ' – user763648

+0

Oparłem swoją odpowiedź na tym: https://dev.mysql.com/doc/connector-j /en/connector-j-usagenotes-tomcat.html Poniższy fragment kodu ilustruje sposób wyboru tej opcji: validationQuery /* ping */ Zauważ, że/* ping */musi być dokładnie określona. – Mike

0

W my.cnf swojej mysql ustaw następujące właściwości do wielkiej wartości jak 365 dni -

wait_timeout = 31536000
interactive_timeout = 31536000

Wartość sesja wait_timeout zostanie zainicjowany z globalnym wait_timeout wartości dla połączeń nieinterakcyjnych oraz z globalną wartością interactive_timeout dla połączeń interaktywnych.

PS - Obie wartości są podane w sekundach.

Powiązane problemy