Question

Je suis récemment passé à Spring Framework au lieu de gérer manuellement JDBC, ce qui est généralement une bonne transition. Cependant, un programme a commencé à avoir d’étranges problèmes: si la base de données est lente, l’appel getJdbcTemplate (). Update (...) ne renvoie parfois jamais.

Après quelques recherches, je suis passé d’Apache DBCP à C3PO , mais le problème persiste. est revenu.

Voici le code que j'utilise:

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");
        }
    }
}

Voici à quoi cela ressemble dans le fichier journal:

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

C’est là que le code se bloque. Habituellement, ça continue comme ça:

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

Je ne sais pas pourquoi je ne reçois aucun message de journal de Spring Framework lui-même. J'ai ajouté ces lignes dans mon code principal:

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

Le message de test indique, mais rien d’autre. Désolé pour divergence.

J'ai remarqué un ralentissement avant le blocage. La dernière fois que la requête a été exécutée avec succès, il a fallu une minute et demie pour terminer, au lieu des 200 ms habituels. La prochaine fois, je le laisse fonctionner pendant 25 minutes avant de mettre fin au processus.

Je sais que ma base de données (InnoDB), sur laquelle je travaille, me pose quelques problèmes, mais après un certain délai, Spring Framework vient d'abandonner " et se bloque.

Tout conseil serait apprécié.

Était-ce utile?

La solution

Le problème a finalement été évité en résolvant le problème de base de données sous-jacent.

J'utilisais une table InnoDB en tant que file d'attente de travail, ce qui voulait dire que j'avais ajouté et supprimé beaucoup d'éléments. La table n'a jamais eu trop de lignes à un moment donné, mais apparemment InnoDB ne peut pas gérer ce type de travail ou, comme l'a dit mon ami administrateur de base de données, "la suppression de lignes d'une table ne fait rien pour la performance".

Après être passé à une stratégie de base de données beaucoup plus folle, qui consistait à créer et à supprimer des tables tout le temps, les performances étaient bien meilleures et les blocages ont disparu.

Donc, je suppose que ce que je dis, c'est que le commentaire de Skaffman était probablement juste. Cela n’a rien à voir avec le printemps.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top