我的 Java Hibernate 应用程序使用准备语句池吗?
Is my Java Hibernate application using Prepared Statement Pooling?
我正在使用 Hibernate 4.3.11.Final 和 H2 1.3.172 数据库,我在一个缓慢的 linux 盒子上分析我的应用程序,发现它在特定的 [=48] 上花费了更多时间=] INSERT 然后其他任何东西。似乎准备好的语句没有被缓存,因为准备好的语句的数量似乎与执行的语句的数量大致相同。
我理解对了吗(我用的是Yourkit Profiler)
我的HibernateUtilclass配置如下
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);
}
我认为缓存不是问题所在。如果您在每次插入时都打开一个新交易,并且总是使用不同的线程插入您的歌曲 table,那么您可能会因打开的交易而阻塞自己。多线程很容易导致错误,尤其是在打开数据库事务时。
在 H2 中,准备好的语句在连接级别缓存。使用 hibernate.c3p0.max_size=200
时,您可能会打开如此多的连接,以至于每次用户执行操作时,他都会获得不同的 H2 连接。
与其他 RDBMS 相比,本地内存 H2 的连接成本最低。尝试删除 C3P0 并使用单个 H2 连接进行测试。这应该确认准备好的语句由 JDBC 驱动程序缓存。
在大多数情况下,连接越少越好。在您的情况下,对于单个用户和多个线程,您的机器不太可能有 200 个 CPU 来充分利用 hibernate.c3p0.max_size=200
.
自 JDBC 3.0 起,将 setMaxStatements(n) 设置为 n 为正数将启用语句池,从而启用缓存。
如果有人使用 Oracle JDBC 驱动程序,您可以通过以下任何方法验证缓存
连接上,
if (conn.getImplicitCachingEnabled())
System.out.println("\nimplicit caching enabled");
else
System.out.println("\nimplicit caching disabled");
关于声明,
int creationState = stmt.creationState();
switch(creationState) {
case 0:
System.out.println("\nCreation state: new");
break;
case 1:
System.out.println("\nCreation state: from the implicit cache");
break;
case 2:
System.out.println("\nCreation state: from the explicit cache");
break;
}
我正在使用 Hibernate 4.3.11.Final 和 H2 1.3.172 数据库,我在一个缓慢的 linux 盒子上分析我的应用程序,发现它在特定的 [=48] 上花费了更多时间=] INSERT 然后其他任何东西。似乎准备好的语句没有被缓存,因为准备好的语句的数量似乎与执行的语句的数量大致相同。
我理解对了吗(我用的是Yourkit Profiler)
我的HibernateUtilclass配置如下
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);
}
我认为缓存不是问题所在。如果您在每次插入时都打开一个新交易,并且总是使用不同的线程插入您的歌曲 table,那么您可能会因打开的交易而阻塞自己。多线程很容易导致错误,尤其是在打开数据库事务时。
在 H2 中,准备好的语句在连接级别缓存。使用 hibernate.c3p0.max_size=200
时,您可能会打开如此多的连接,以至于每次用户执行操作时,他都会获得不同的 H2 连接。
与其他 RDBMS 相比,本地内存 H2 的连接成本最低。尝试删除 C3P0 并使用单个 H2 连接进行测试。这应该确认准备好的语句由 JDBC 驱动程序缓存。
在大多数情况下,连接越少越好。在您的情况下,对于单个用户和多个线程,您的机器不太可能有 200 个 CPU 来充分利用 hibernate.c3p0.max_size=200
.
自 JDBC 3.0 起,将 setMaxStatements(n) 设置为 n 为正数将启用语句池,从而启用缓存。
如果有人使用 Oracle JDBC 驱动程序,您可以通过以下任何方法验证缓存
连接上,
if (conn.getImplicitCachingEnabled())
System.out.println("\nimplicit caching enabled");
else
System.out.println("\nimplicit caching disabled");
关于声明,
int creationState = stmt.creationState();
switch(creationState) {
case 0:
System.out.println("\nCreation state: new");
break;
case 1:
System.out.println("\nCreation state: from the implicit cache");
break;
case 2:
System.out.println("\nCreation state: from the explicit cache");
break;
}