2013-04-26 7 views
7

Ho un calcolo molto semplice che produce lettere matrici trova probabilmente tutte le parole nella matrice. Le lettere nella parola sono celle adiacenti.Come tracciare e prevenire il deadlock apparso in c3po che è in esecuzione in processi separati?

for (int i = 0; i < 500; i++) { 
     System.out.println(i); 
     Matrix matrix = new Matrix(4); 
     matrix.scanWordsRandomly(9); 
     matrix.printMatrix(); 
     System.out.println(matrix.getSollSize()); 
     matrix.write_to_db(); 
    } 

Ecco il codice persistente.

public void write_to_db() { 
    Session session = null; 
    try { 
     session = HibernateUtil.getSessionFactory().openSession(); 
     session.beginTransaction(); 
     Matrixtr onematrixtr = new Matrixtr(); 
     onematrixtr.setDimension(dimension); 
     onematrixtr.setMatrixstr(this.toString()); 
     onematrixtr.setSolsize(getSollSize()); 
     session.save(onematrixtr); 
     for (Map.Entry<Kelimetr, List<Cell>> sollution : sollutions.entrySet()) { 
      Kelimetr kelimetr = sollution.getKey(); 
      List<Cell> solpath = sollution.getValue(); 
      Solstr onesol = new Solstr(); 
      onesol.setKelimetr(kelimetr); 
      onesol.setMatrixtr(onematrixtr); 
      onesol.setSoltext(solpath.toString().replace("[", "").replace("]", "").replace("true", "").replace("false", "")); 
      session.save(onesol); 
     } 

     session.getTransaction().commit(); 
     session.close(); 

    } 
    catch (HibernateException he) { 
     System.out.println("DB Error : " + he.getMessage()); 
     session.close(); 
    } 
    catch (Exception ex) { 
     System.out.println("General Error : " + ex.getMessage()); 
    } 
} 

Questo è il file di configurazione di ibernazione.

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> 
<hibernate-configuration> 
    <session-factory> 
    <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> 
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> 
    <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/kelimegame_db_dev?autoReconnect=true&amp;useUnicode=true&amp;characterEncoding=UTF-8</property> 
    <property name="hibernate.connection.username">root</property> 
    <property name="hibernate.connection.password">!.Wlu9RrCA</property> 
    <property name="hibernate.show_sql">false</property> 
    <property name="hibernate.query.factory_class">org.hibernate.hql.classic.ClassicQueryTranslatorFactory</property> 
    <property name="hibernate.format_sql">false</property> 
    <!-- Use the C3P0 connection pool provider --> 
    <property name="hibernate.c3p0.acquire_increment">50</property> 
    <property name="hibernate.c3p0.min_size">10</property> 
    <property name="hibernate.c3p0.max_size">100</property> 
    <property name="hibernate.c3p0.timeout">300</property> 
    <property name="hibernate.c3p0.max_statements">5</property> 
    <property name="hibernate.c3p0.idle_test_period">3000</property> 
    <mapping resource="kelimegame/entity/Progress.hbm.xml"/> 
    <mapping resource="kelimegame/entity/Solstr.hbm.xml"/> 
    <mapping resource="kelimegame/entity/Kelimetr.hbm.xml"/> 
    <mapping resource="kelimegame/entity/User.hbm.xml"/> 
    <mapping resource="kelimegame/entity/Achievement.hbm.xml"/> 
    <mapping resource="kelimegame/entity/Matrixtr.hbm.xml"/> 
    </session-factory> 
</hibernate-configuration> 

Dopo aver trovato tutte le possibili soluzioni, continuo la matrice e le soluzioni utilizzando l'ibernazione. Sto anche usando la libreria c3pO. Non sto generando alcun thread. Tutto il lavoro viene svolto in un modo iterativo molto semplice. Ma sto eseguendo il barattolo in processi separati. Da diversi terminali sto eseguendo questo:

java -jar NewDB.jar 

ho avuto una situazione di stallo come segue:

Apr 25, 2013 8:38:05 PM com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector run 
WARNING: com[email protected]7f0c09f9 -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks! 
Apr 25, 2013 9:08:23 PM com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector run 
WARNING: com[email protected]7f0c09f9 -- APPARENT DEADLOCK!!! Complete Status: 
    Managed Threads: 3 
    Active Threads: 3 
    Active Tasks: 
     com[email protected]2933f261 
      on thread: C3P0PooledConnectionPoolManager[identityToken->z8kfsx8uibeyqevbbapc|4045cf35]-HelperThread-#1 
     com[email protected]116dd369 
      on thread: C3P0PooledConnectionPoolManager[identityToken->z8kfsx8uibeyqevbbapc|4045cf35]-HelperThread-#0 
     com[email protected]41529b6f 
      on thread: C3P0PooledConnectionPoolManager[identityToken->z8kfsx8uibeyqevbbapc|4045cf35]-HelperThread-#2 
    Pending Tasks: 
     com[email protected]165ab5ea 
     com[email protected]1d5d211d 
     com[email protected]4d2905fa 
Pool thread stack traces: 
    Thread[C3P0PooledConnectionPoolManager[identityToken->z8kfsx8uibeyqevbbapc|4045cf35]-HelperThread-#1,5,main] 
     com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:662) 
    Thread[C3P0PooledConnectionPoolManager[identityToken->z8kfsx8uibeyqevbbapc|4045cf35]-HelperThread-#0,5,main] 
     com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:662) 
    Thread[C3P0PooledConnectionPoolManager[identityToken->z8kfsx8uibeyqevbbapc|4045cf35]-HelperThread-#2,5,main] 
     com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:662) 


Apr 25, 2013 9:41:29 PM com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector run 
WARNING: com[email protected]7f0c09f9 -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks! 
Apr 25, 2013 9:55:18 PM com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector run 
WARNING: com[email protected]7f0c09f9 -- APPARENT DEADLOCK!!! Complete Status: 
    Managed Threads: 3 
    Active Threads: 3 
    Active Tasks: 
     com[email protected]5a337b7d 
      on thread: C3P0PooledConnectionPoolManager[identityToken->z8kfsx8uibeyqevbbapc|4045cf35]-HelperThread-#0 
     com[email protected]69f079ce 
      on thread: C3P0PooledConnectionPoolManager[identityToken->z8kfsx8uibeyqevbbapc|4045cf35]-HelperThread-#1 
     com[email protected]2accf9b8 
      on thread: C3P0PooledConnectionPoolManager[identityToken->z8kfsx8uibeyqevbbapc|4045cf35]-HelperThread-#2 
    Pending Tasks: 
     com[email protected]771eb4fb 
     com[email protected]fc07d6 
     com[email protected]2266731b 
     com[email protected]740f0341 
     com[email protected]59edbee 
     com[email protected]78e924 
     com[email protected]2123aba 
     com[email protected]7acd8a65 
Pool thread stack traces: 
    Thread[C3P0PooledConnectionPoolManager[identityToken->z8kfsx8uibeyqevbbapc|4045cf35]-HelperThread-#0,5,main] 
     java.text.NumberFormat.getInstance(NumberFormat.java:769) 
     java.text.NumberFormat.getInstance(NumberFormat.java:393) 
     java.text.MessageFormat.subformat(MessageFormat.java:1262) 
     java.text.MessageFormat.format(MessageFormat.java:860) 
     java.text.Format.format(Format.java:157) 
     java.text.MessageFormat.format(MessageFormat.java:836) 
     com.mysql.jdbc.Messages.getString(Messages.java:106) 
     com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:2552) 
     com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3002) 
     com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2991) 
     com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3532) 
     com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:943) 
     com.mysql.jdbc.MysqlIO.secureAuth411(MysqlIO.java:4113) 
     com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1308) 
     com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2336) 
     com.mysql.jdbc.ConnectionImpl.connectWithRetries(ConnectionImpl.java:2176) 
     com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2158) 
     com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:792) 
     com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:47) 
     sun.reflect.GeneratedConstructorAccessor7.newInstance(Unknown Source) 
     sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) 
     java.lang.reflect.Constructor.newInstance(Constructor.java:525) 
     com.mysql.jdbc.Util.handleNewInstance(Util.java:411) 
     com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:381) 
     com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:305) 
     com.mchange.v2.c3p0.DriverManagerDataSource.getConnection(DriverManagerDataSource.java:134) 
     com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:183) 
     com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:172) 
     com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.acquireResource(C3P0PooledConnectionPool.java:188)Killed 
[email protected]:~/NetBeansProjects/NewDB/dist$ 

La mia domanda è la seguente:

  1. Può questa situazione di stallo in c3po accadere dal momento che sto eseguendo il programma nei processi separati ?
  2. Devo utilizzare un processo e più thread all'interno di questo processo ?
  3. Come posso tracciare questo deadlock capirne la causa? C'è un modo per rintracciare più JVM causando deadlock?
+0

stai utilizzando anche mcache, giusto? Posso dire dallo stacktrace qui: * com.mchange.v2.async * – Eugene

+0

quale versione di c3p0 stai usando? – Eugene

+0

c3p0-0.9.2 è la versione. – cgon

risposta

8

questo è interessante.

hai pubblicato due distinti DEADLOCKS APPARENT. il primo è causato da c3p0 che tenta di chiudere() Connessioni, e quelle operazioni close() non hanno successo né falliscono con un'eccezione in modo tempestivo. il secondo DEADLOCK APPARENT mostra problemi con l'acquisizione di Connection: c3p0 sta tentando di acquisire nuove connessioni e tali tentativi non sono né riusciti né falliscono con un'eccezione in modo tempestivo. il fatto che operazioni molto diverse siano bloccanti suggerisce che potrebbe essere un problema più generale con i tuoi dbms che si bloccano sotto lo stress di quello che stai facendo o qualcosa di simile. non dovrebbe essere un problema eseguire più processi sul tuo database, ma devi essere consapevole dei limiti.

ci sono un paio di cose interessanti sulla configurazione:

1) hibernate.c3p0.max_statements = 5 è una pessima idea, su quasi tutta la piscina e in particolare sulle piscine, questo di grandi dimensioni. hai fino a 100 connessioni e stai permettendo solo un totale di 5 dichiarazioni da memorizzare nella cache tra tutte loro. questo potrebbe stressare sia il pool che il DBMS, dato che continuerai a sfogarti attraverso PreparedStatements e la cache delle istruzioni fa un sacco di contabilità a riguardo. potresti aver inteso che si tratta di 5 istruzioni memorizzate nella cache per connessione, ma non è quello che hai configurato. hai impostato un limite globale per il tuo pool. forse provare hibernate.c3p0.maxStatementsPerConnection = 5 invece? oppure imposta max_statements su zero per disattivare la memorizzazione delle istruzioni, almeno finché non risolvi il deadlock.vedi http://www.mchange.com/projects/c3p0/#configuring_statement_pooling

2) se si sta eseguendo il calcolo in più processi anziché in più thread, è veramente necessario che ogni processo contenga 50 - 100 connessioni? è probabile che le cose si congelino semplicemente perché si stanno sottolineando i dbms con troppe connessioni in sospeso poiché ciascuno dei vostri processi multipli acquisisce molte connessioni pesanti in termini di risorse. non hai bisogno di più Connessioni in qualsiasi processo rispetto a quanto potresti avere thread client in esecuzione contemporaneamente all'interno di quel processo. imposterei hibernate.c3p0.acquire_increment e probabilmente hibernate.c3p0.max_size a valori molto più piccoli.

3) se davvero hai bisogno che tutte queste connessioni funzionino contemporaneamente, puoi ridurre la vulnerabilità dei tuoi pool a deadlock aumentando il parametro di configurazione numHelperThreads ad un valore maggiore del suo valore predefinito 3. probabilmente vuoi che numHelperThreads sia qualcosa come il doppio del numero di core disponibili sulla tua macchina. dato che stai eseguendo più processi, potresti scoprire che stai saturando la tua CPU, e questo sta bloccando le cose. quindi attenzione.

in pratica, prova ad aggiornare la configurazione in modo da utilizzare le risorse (handle di file, connessioni di rete, CPU) nel modo più efficiente possibile e in modo da non sovraccaricare inutilmente il pool/statement cache/dbms più del necessario essere.

se questi suggerimenti non risolvono il problema, si prega di inviare la configurazione di riempimento dei pool. c3p0 fa il dump della sua config a livello INFO sull'inizializzazione del pool.

buona fortuna!

Problemi correlati