我的Java Hibernate应用程序是否使用Prepared Statement Pooling?

问题描述 投票:8回答:2

我正在使用Hibernate 4.3.11.Final和H2 1.3.172数据库,我在一个缓慢的Linux机器上分析我的应用程序,并发现它花费更多的时间在特定的SQL INSERT然后其他任何东西。似乎准备好的语句没有被缓存,因为准备好的语句的数量似乎与执行的语句数量大致相同。

我是否解释了这一点(我正在使用Yourkit Profiler)

enter image description here

我的HibernateUtil类配置如下

public static Configuration getInitializedConfiguration()
    {
        Configuration config = new Configuration();

        config.setProperty(Environment.DRIVER,"org.h2.Driver");
        config.setProperty(Environment.URL,"jdbc:h2:"+Db.DBFOLDER+"/"+Db.DBNAME+";FILE_LOCK=SOCKET;MVCC=TRUE;DB_CLOSE_ON_EXIT=FALSE;CACHE_SIZE=50000");
        config.setProperty(Environment.DIALECT,"org.hibernate.dialect.H2Dialect");
        System.setProperty("h2.bindAddress", InetAddress.getLoopbackAddress().getHostAddress());
        config.setProperty("hibernate.connection.username","jaikoz");
        config.setProperty("hibernate.connection.password","jaikoz");
        config.setProperty("hibernate.c3p0.numHelperThreads","10");
        config.setProperty("hibernate.c3p0.min_size","20");
        //Consider that if we have lots of busy threads waiting on next stages could we possibly have alot of active
        //connections.
        config.setProperty("hibernate.c3p0.max_size","200");
        config.setProperty("hibernate.c3p0.timeout","300");
        config.setProperty("hibernate.c3p0.maxStatementsPerConnection","50");
        config.setProperty("hibernate.c3p0.idle_test_period","3000");
        config.setProperty("hibernate.c3p0.acquireRetryAttempts","10");
        addEntitiesToConfig(config);
        return config;
    }

我想知道我是否错误地配置了它,特别令人困惑的是c3po文档确实与Hibernate配置完全结合了一些参数的名称。

即它是max_size或max_pool_size

它是一个单用户多线程应用程序,理想情况下我希望在应用程序的持续时间内缓存所有准备好的语句,因为只有大约50个不同的语句。

我每次都明白这一点

session = HibernateUtil.beginTransaction();

将从池中获取连接,如果该特定连接先前已准备好现在需要的语句,则它可以使用该预准备语句而无需编译新语句。

如果准备好的陈述不存在则准备好。

如果已经为此连接准备了五十个语句,那么最旧的语句将被删除。

占用更多时间的这个特定查询使用如下

public static void saveMatchedToRelease(Session session,Integer reportId, Integer recNo, SongFieldKey songFieldKey, SongChangeType type, String original, String edited)
{
    SongChanges sc = new SongChanges();
    sc.setReportId(reportId);
    sc.setRecNo(recNo);
    sc.setField(songFieldKey);
    sc.setType(type);
    sc.setOriginalValue(original);
    sc.setNewValue(edited);
    session.save(sc);
}
java hibernate profiler c3p0
2个回答
1
投票

在H2中,预处理语句缓存在连接级别上。使用hibernate.c3p0.max_size=200,您可能有这么多打开的连接,每次用户执行操作时,他将获得不同的H2连接。

与其他RDBMS相比,本地内存H2具有最小的连接成本。尝试删除C3P0并使用单个H2连接进行测试。这应该确认JDBC驱动程序缓存预准备语句。

在大多数情况下,连接越少越好。在您的情况下,只有一个用户和多个线程,您的机器不可能有200个CPU来充分利用hibernate.c3p0.max_size=200


0
投票

我不认为缓存是问题。如果您使用每个插入打开一个新事务,并且始终使用不同的线程插入到您的歌曲表中,那么您可能会使用打开的事务阻止自己。多线程很容易导致错误,尤其是在打开数据库事务时。

© www.soinside.com 2019 - 2024. All rights reserved.