3

最近、JDBCを手動で処理する代わりにSpring Frameworkに切り替えましたが、これはほとんどの場合、適切な移行です。ただし、あるプログラムで奇妙な問題が発生し始めました。データベースが遅い場合、呼び出すときにデータベースがgetJdbcTemplate().update( ... )戻らないことがあります。

少し調べた後、Apache DBCPからC3POに切り替えましたが、それでも問題は再発しました。

これが私が使用しているコードです:

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

ログファイルでは次のようになります。

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

ここにコードがぶら下がっています。通常、次のようになります。

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

SpringFramework自体からログメッセージが表示されない理由がわかりません。メインコードに次の行を追加しました。

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

テストメッセージが表示されますが、他には何も表示されません。発散してすみません。

ハングする前に速度が低下していることに気づきました。クエリが最後に正常に実行されたとき、通常の200ミリ秒ではなく、完了するのに1分半かかりました。次回は、プロセスを強制終了する前に25分間実行しました。

作業中のデータベース(InnoDB)に問題があることはわかっていますが、これはタイムアウト後、SpringFrameworkが「あきらめて」ハングするようです。

何かアドバイスをいただければ幸いです。

4

1 に答える 1

3

最終的に、根本的な DB の問題を修正することで、問題は回避されました。

私は InnoDB テーブルを作業キューとして使用していました。つまり、大量の項目を追加および削除しました。特定の時間にテーブルに行が多すぎることはありませんでしたが、どうやら InnoDB はこの種の作業を処理できないか、DBA の友人が言ったように、「テーブルから行を削除してもパフォーマンスは向上しません」。

常にテーブルの作成と削除を含む、よりクレイジーなデータベース戦略に切り替えた後、パフォーマンスは大幅に改善され、ハングはなくなりました.

だから私が言っているのは、スカフマンのコメントはおそらく正しかったということです。これは春とは何の関係もありませんでした。

于 2009-10-29T21:33:22.400 に答える