Domanda

Di recente sono passato a Spring Framework invece di gestire manualmente JDBC, ed è soprattutto una buona transizione. Un programma ha iniziato a presentare strani problemi: se il database è lento, quando si chiama getJdbcTemplate (). Update (...) a volte non ritorna mai.

Dopo aver studiato un po ', sono passato da Apache DBCP a C3PO , ma il problema continua è tornato.

Ecco il codice che sto usando:

public class MyDao extends SimpleJdbcDaoSupport {
    private static Logger logger = Logger.getLogger(MyDao.class);

    public MyDao(Config config) {
        super();

        ComboPooledDataSource cpds = new ComboPooledDataSource();
        try {
            cpds.setDriverClass("com.mysql.jdbc.Driver");
        } catch (PropertyVetoException e) {
            throw new RuntimeException(e);
        }
        cpds.setUser("username");
        cpds.setPassword("password");
        cpds.setJdbcUrl("jdbc:mysql://localhost/schema" + 
                        "?useUnicode=true&characterEncoding=UTF-8");
        cpds.setMaxStatements( 180 );
        cpds.setPreferredTestQuery("SELECT 1");
        cpds.setTestConnectionOnCheckout(true);

        this.setDataSource(cpds);
    }

    public void addToWorkQueue(String item) {
        long[] ids = Utils.getItemIds(item);

        try {
            logger.debug("About to insert to work table");
            getJdbcTemplate().update(
                    "INSERT IGNORE INTO work " +
                    "SELECT * FROM queue WHERE id_1 = ? AND id_2 = ?",
                    new Object[] { ids[0], ids[1] }
            );
        } finally {
            logger.debug("Updated work table");
        }
    }
}

Ecco come appare nel file di registro:

2009-07-29 17:37:13.570 com.mycomp.MyDao About to insert into work table
2009-07-29 17:37:13.570 com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool Testing PooledConnection [com.mchange.v2.c3p0.impl.NewPooledConnection@170984c] on CHECKOUT.
2009-07-29 17:37:13.571 com.mchange.v2.c3p0.stmt.GooGooStatementCache checkinAll(): com.mchange.v2.c3p0.stmt.GlobalMaxOnlyStatementCache stats -- total size: 1; checked out: 0; num connections: 1; num keys: 1
2009-07-29 17:37:13.571 com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool Test of PooledConnection [com.mchange.v2.c3p0.impl.NewPooledConnection@170984c] on CHECKOUT has SUCCEEDED.
2009-07-29 17:37:13.571 com.mchange.v2.resourcepool.BasicResourcePool trace com.mchange.v2.resourcepool.BasicResourcePool@d402dd [managed: 3, unused: 2, excluded: 0] (e.g. com.mchange.v2.c3p0.impl.NewPooledConnection@170984c)
2009-07-29 17:37:13.571 com.mchange.v2.c3p0.stmt.GooGooStatementCache com.mchange.v2.c3p0.stmt.GlobalMaxOnlyStatementCache ----> CACHE HIT
2009-07-29 17:37:13.571 com.mchange.v2.c3p0.stmt.GooGooStatementCache checkoutStatement: com.mchange.v2.c3p0.stmt.GlobalMaxOnlyStatementCache stats -- total size: 1; checked out: 1; num connections: 1; num keys: 1

Qui è dove si blocca il codice. Di solito continua così:

2009-07-29 17:37:13.762 com.mchange.v2.c3p0.stmt.GooGooStatementCache checkinStatement(): com.mchange.v2.c3p0.stmt.GlobalMaxOnlyStatementCache stats -- total size: 1; checked out: 0; num connections: 1; num keys: 1
2009-07-29 17:37:13.763 com.mchange.v2.c3p0.stmt.GooGooStatementCache checkinAll(): com.mchange.v2.c3p0.stmt.GlobalMaxOnlyStatementCache stats -- total size: 1; checked out: 0; num connections: 1; num keys: 1
2009-07-29 17:37:13.763 com.mchange.v2.resourcepool.BasicResourcePool trace com.mchange.v2.resourcepool.BasicResourcePool@d402dd [managed: 3, unused: 2, excluded: 0] (e.g. com.mchange.v2.c3p0.impl.NewPooledConnection@170984c)
2009-07-29 17:37:13.763 com.mycomp.MyDao Updated work table

Non so perché non ricevo alcun messaggio di log dallo stesso Spring Framework. Ho aggiunto queste righe nel mio codice principale:

Logger springLogger = Logger.getLogger("org.springframework");
springLogger.setLevel(Level.TRACE);
springLogger.debug("testing spring logger");

Viene visualizzato il messaggio di prova, ma nient'altro. Ci scusiamo per il divergere.

Ho notato un rallentamento prima della caduta. L'ultima volta che la query è stata eseguita correttamente ci sono voluti un minuto e mezzo per terminare, invece dei soliti 200ms. La prossima volta, l'ho lasciato funzionare per 25 minuti prima di interrompere il processo.

So di avere alcuni problemi con il mio database (InnoDB), su cui sto lavorando, ma questo sembra come dopo un timeout, Spring Framework appena "cede " e si blocca.

Qualsiasi consiglio sarebbe apprezzato.

È stato utile?

Soluzione

Alla fine, il problema è stato evitato risolvendo il problema DB sottostante.

Stavo usando una tabella InnoDB come coda di lavoro, il che significava che avevo aggiunto e rimosso molti elementi. La tabella non ha mai avuto troppe righe in un dato momento, ma a quanto pare InnoDB non può gestire questo tipo di lavoro, o come ha detto il mio amico DBA, "l'eliminazione delle righe da una tabella non fa nulla per le prestazioni".

Dopo essere passati a una strategia db molto più folle, che ha comportato la creazione e la caduta di tabelle in ogni momento, le prestazioni sono state notevolmente migliorate e le interruzioni sono andate via.

Quindi immagino che quello che sto dicendo sia, il commento di Skaffman era probabilmente giusto. Questo non aveva nulla a che fare con la primavera.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top