代码之家  ›  专栏  ›  技术社区  ›  Paul Taylor

我的Java Hibernate应用程序是否使用了准备好的语句池?

  •  8
  • Paul Taylor  · 技术社区  · 6 年前

    我正在使用Hibernate 4.3.11.Final和H2 1.3.172数据库,我在一个缓慢的linux机器上分析我的应用程序,发现它在一个特定的SQL插入上花费的时间比其他任何东西都多。似乎还没有缓存准备好的语句,因为准备好的语句数似乎与执行的语句数差不多。

    我解释对了吗(我用的是你的工具包剖析器)

    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配置结合在一起。

    i、 是的 最大尺寸 最大池大小

    它是一个单用户多线程应用程序,理想情况下,我希望在应用程序运行期间缓存所有准备好的语句,因为只有大约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);
    }
    
    2 回复  |  直到 6 年前
        1
  •  1
  •   Karol Dowbecki    6 年前

    在H2中,准备好的语句缓存在连接级别。与 hibernate.c3p0.max_size=200 有一个机会,你有这么多开放的连接,每次用户执行操作,他将得到一个不同的H2连接。

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

    在大多数情况下,较少的联系会更好。在您的情况下,对于一个用户和多个线程,您的计算机不太可能有200个CPU来充分利用 休眠.c3p0.max_size=200 .

        2
  •  0
  •   Arquillian    6 年前

    我认为缓存不是问题所在。如果每次插入都打开一个新事务,并且总是用不同的线程插入到songs表中,则可能会用打开的事务阻塞自己。多线程很容易导致错误,特别是在开放数据库事务中。