2009-10-02 11 views
14

mam ten błąd z kodem produkcji:rozmnażać com.mysql.jdbc.exceptions.jdbc4.CommunicationsException z konfiguracji wiosny, hibernacji i C3P0

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException : ostatni pakiet odebrany z serwera was36940 sekund ago.The ostatni pakiet wysłany pomyślnie z serwerem zostało 36940 sekund temu który jest dłuższy niż skonfigurowany serwer wartości „wait_timeout”. Należy rozważyć albo wygasa i/lub połączenia testowego ważność przed użyciem w aplikacji, zwiększenie serwer skonfigurowany wartości limitu czasu klienta lub przy użyciu Connector/J nieruchomość połączenie „autoReconnect = true”, aby uniknąć tego problem.

Teraz próbuję odtworzyć problem lokalnie i go naprawić. I setup kontekst wiosna w następujący sposób:

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" 
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" 
    destroy-method="close" p:driverClass="com.mysql.jdbc.Driver" 
    p:jdbcUrl="jdbc:mysql://localhost:3306/test?userUnicode=yes&amp;characterEncoding=UTF-8&amp" 
    p:idleConnectionTestPeriod="120" p:initialPoolSize="1" p:maxIdleTime="1800" 
    p:maxPoolSize="1" p:minPoolSize="1" p:checkoutTimeout="1000" 

/> 

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> 
    <property name="dataSource" ref="dataSource"/> 
    <property name="hibernateProperties"> 
     <value> 
      hibernate.connection.provider_class = org.hibernate.connection.C3P0ConnectionProvider 
      hibernate.dialect=org.hibernate.dialect.MySQL5Dialect 
      hibernate.default_schema=platform_server_original 
      hibernate.show_sql=false 
     </value> 
    </property> 
    <property name="mappingResources"> 
     <list> 
      <value>sometables.hbm.xml</value> 
     </list> 
    </property> 
</bean> 

Wtedy mogę ustawić mysql wait_timeout do 10 sekund, a następnie uruchomić mój test, który jest w zasadzie otworzyć połączenie, wykonać zapytanie, zamknąć go, więc wraca do basenu , następnie uśpij wątek przez 15 sekund, a następnie ponownie otwórz połączenie i ponownie wykonaj zapytanie, aby się zepsuł. Jednak mam tylko podobny błąd:

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Komunikacja awaria łącza

Ostatni pakiet wysyłany do serwera wynosił 16 ms temu.

Zastanawiam się, czy te dwa błędy są takie same, czy są różne? Zrobiłem kilka badań i wydaje się, że oba błędy sprowadzają się do tego samego rozwiązania: użycie właściwości "testConnectionOnCheckout = true". Jednak zgodnie z dokumentem c3p0 jest to bardzo kosztowna kontrola. Zaleca użycie "idleConnectionTestPeriod", ale już ustawiłem to na 120 sekund. Jaką wartość powinienem użyć, aby właściwie zweryfikować bezczynne połączenie?

Więc zasadniczo pytam o dwie rzeczy: 1. w jaki sposób mogę odtworzyć błąd, który dostałem w kodzie produkcyjnym? 2. jak to naprawić?

Dzięki!

+0

Pierwotny błąd z produkcji mówi o czasie ponad 10 godzin, a dzieje się, gdy połączenie jest zaznaczone, kiedy system jest pierwszy używane rano? Czy nie możesz ustawić minimalnego rozmiaru puli na 0 lub wystawić pulę przez JXB i opróżnić go przed rozpoczęciem dnia roboczego? – SteveD

+0

@fei - rozwiązałeś to? Bądź zainteresowany, aby dowiedzieć się, jaki był wynik. –

+1

Skończyło się na użyciu następujących 2 właściwości: testConnectionOnCheckout = "true" preferredTestQuery = "select 1" Nie jest to najbardziej optymalne rozwiązanie, ale przynajmniej rozwiązuje problem. – fei

Odpowiedz

0

Fei - może być jedną z kilku rzeczy, nie można tak naprawdę powiedzieć na podstawie opublikowanych do tej pory informacji.

Sugerujemy dodanie numerów wersji MySQL/Spring/Hibernate/C3PO/JDBC do pytania, na wypadek, gdyby znany był problem.

Komunikat o błędzie produkcyjnym jest często występujący, z wieloma możliwymi przyczynami źródłowymi. Niektóre przewody dla Ciebie:

  1. Błąd produkcja może wskazywać nie, że aplikacja jest zwalniania połączenia z powrotem do puli kiedy z nim zrobić, zapobiegając C3P0 od sprawdzenia go.(The C3P0 sprawdza bezczynności może być stosowana tylko do połączeń niezaznaczone-out).

  2. Sprawdź, C3P0 naprawdę działa (może być używany „wanilia” połączenia czy nie). W swoim badaniu jeśli ustawione (np) MySql wait_timeout = 10, gwint aplikacja sen = 35, a idleConnectionTestPeriod = 30, jeśli pooling pracuje wyjątek powinien odejść.

  3. Na kosztem bezczynnych kontroli: nie rozważyć użycie domyślnych getTables() - może ustawić preferredTestQuery do czegoś taniego (-er) „wybierz 1” może dla MySQL?

0

Aby odtworzyć swój błąd, ustawić limit czasu połączenia we właściwościach MySQL do bardzo niskiej wartości, czyli 2 ms i uruchom kwerendę wiadomo, że ma długi czas przetwarzania. Możesz ustawić właściwość timeout w ciągu połączenia MySQL lub przez właściwość, jeśli używasz plików właściwości do skonfigurowania połączenia JDBC. Możesz sprawdzić Javadocs na swoim specyficznym połączeniu jaxax.sql.DataSource i dokumentach MySQL, aby dowiedzieć się, jak to zrobić.

+1

Wartość wait_timeout MySQL to sekundy, a nie ms. Więc nie można go ustawić na 2ms? –

3

Miałem podobne problemy z MySQL i pulą połączeń. Problem polega na informowaniu puli połączeń, że czas bezczynności wynosi 30 minut, ale baza danych odcina połączenie po 10 sekundach. Ponieważ twój okres nieaktywności połączenia wynosi 120 sekund, pozostawia nieco mniej niż 110 sekund, aby pula wykorzystała zerwane połączenie!

użyję następujących ustawień dla produkcji:

MySQL: 
wait_timeout=75 
C3P0: 
maxIdleTime=60 
idleConnectionTestPeriod=55 
Powiązane problemy