2014-12-17 14 views
7

dostaję ten błąd z aplikacji Java:Nie wolno po operacji połączenia zamknięte

com.mchange.v2.c3p0.impl.NewPooledConnection - [c3p0] Another 
error has occurred [  
com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: 
No operations allowed after connection closed. ] which will not be 
reported to listeners! 

kodu Java:

try { 
    sessionFactory.beginTransaction(); 
    //... 
    sessionFactory.commitTransaction(); 
} catch (Exception e) { 
    sessionFactory.rollbackTransaction(); 
    throw new RuntimeException(e); 
} 

Fabryka sesja:

try { 
    sessionFactory.beginTransaction(); 
    ... 
    sessionFactory.commitTransaction(); 
} catch (Exception e) { 
    sessionFactory.rollbackTransaction(); 
    throw new RuntimeException(e); 
} 

public Transaction beginTransaction() throws HibernateException { 
    try { 
     return sessionFactory.getCurrentSession().beginTransaction(); 
    } catch (HibernateException hex) { 
     LOG.error(String.format("Unable to start database transaction due to exception: %s.", ExceptionUtils.getRootCauseMessage(hex))); 
     throw hex; 
    } 
} 

public void commitTransaction() throws HibernateException { 
    LOG.debug("Committing database transaction."); 
    try { 
     if (sessionFactory.getCurrentSession().getTransaction().isActive()) { 
      sessionFactory.getCurrentSession().getTransaction().commit(); 
     } else { 
      throw new HibernateException("Transaction is no longer Active."); 
     } 
    } catch (HibernateException hex) { 
     LOG.error(String.format("Unable to commit due to exception: %s.", ExceptionUtils.getRootCauseMessage(hex))); 
     throw hex; 
    } 
} 

public void rollbackTransaction() throws HibernateException { 
    LOG.debug("Trying to rollback database transaction after exception."); 
    Session session = sessionFactory.getCurrentSession(); 
    try { 
     if (session.getTransaction().isActive()) { 
      session.getTransaction().rollback(); 
     } else { 
      throw new HibernateException("Transaction is no longer Active."); 
     } 
    } catch (HibernateException hex) { 
     LOG.error(String.format("Unable to rollback due to exception: %s.", ExceptionUtils.getRootCauseMessage(hex))); 
     throw hex; 
    } finally { 
     if (session.isOpen()) { 
      session.close(); 
     } 
    } 
} 

Hibernate i ustawienia C3P0:

<prop key="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</prop> 
<prop key="hibernate.connection.driver_class">com.mysql.jdbc.Driver</prop> 

<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> 
<prop key="hibernate.show_sql">false</prop> 
<prop key="hibernate.current_session_context_class">thread</prop> 
<prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</prop> 
<prop key="hibernate.jdbc.batch_size">20</prop> 
<prop key="hibernate.order_inserts">true</prop> 
<prop key="hibernate.order_updates">true</prop> 
<prop key="hibernate.c3p0.timeout">1800 <!-- seconds --></prop> 
<prop key="hibernate.c3p0.min_size">4</prop> 
<prop key="hibernate.c3p0.max_size">35</prop> 
<prop key="hibernate.c3p0.idle_test_period">240 <!-- seconds --></prop> 
<prop key="hibernate.c3p0.acquire_increment">4</prop> 
<prop key="hibernate.c3p0.max_statements">0</prop> 
<prop key="hibernate.c3p0.preferredTestQuery">SELECT 1</prop> 
<prop key="c3p0.testConnectionOnCheckout">true</prop> 
<prop key="hibernate.connection.oracle.jdbc.ReadTimeout">60000 <!-- milliseconds --></prop> 

Nie wiem, jak połączenie może być nadal używane i ten błąd został zgłoszony. Co powoduje ten błąd?

+0

nie mogę powiedzieć na pewno, nie widząc cały kod, ale czy zamykasz sesję po pomyślnym zatwierdzeniu? Nie widzę tego w powyższym kodzie. Jeśli nie, wyczerpujesz pulę połączeń. –

+0

Sesja jest automatycznie zamykana po zatwierdzeniu transakcji: https://developer.jboss.org/wiki/Sessionsandtransactions?_sscc=t#jive_content_id_Transaction_demarcation_with_plain_JDBC. – tuxx

Odpowiedz

3

Ta metoda Java o nazwie executeQuery:

your_database_connection.createStatement().executeQuery(your_string_query); 

rzuci ten wyjątek:

com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: 
No operations allowed after connection closed. 

jeśli spróbujesz go (executeQuery) prowadzony po wywołaniu:

your_database_connection.close() 

Co dzieje się

Albo próbujesz uzyskać połączenie z bazą danych, ale go nie otrzymujesz, i próbujesz uruchomić kwerendę, która się nie powiedzie. Lub masz połączenie, które poniosło jakiś problem i zostało zamknięte, a Ty próbowałeś uruchomić przez to kolejne zapytanie.

Rozwiązanie

Zakładając, że utracił połączenie z problemów sieciowych lub coś, co nie jest twoja wina, a następnie umieścić kod, który próbuje zapytanie w bloku try/catch, a w przypadku błędu odczekaj 10 sekund i ponownie połączyć się z bazą danych.

0

Twój idleConnectionTestPeriod wynosi 240, powinien on mniej niż db czeka wartości limitu czasu, zobacz config db, sprawdź wartość jest większa niż 240.

Powiązane problemy