【发布时间】:2014-07-03 21:13:58
【问题描述】:
我正在使用休眠和 c3p0 连接池插入、更新和删除许多分离的对象。 问题是hibernate不会批处理语句,而是执行一个
select @@session.tx_read_only
在每个 session.persist/insert/update/delete(object) 之间。分析 sql-connection 它看起来像这样:
select @@session.tx_read_only
insert...
select @@session.tx_read_only
insert...
select @@session.tx_read_only
insert...
select @@session.tx_read_only
insert...
select @@session.tx_read_only
insert...
select @@session.tx_read_only
选择@@session.tx_rad_only 总是返回“0”(当然)。我是使用无状态会话还是有状态会话都没有关系。由此产生的性能是不可接受的,而且与任何预期相去甚远。
我的休眠配置:
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://127.0.0.1:4040/xy?zeroDateTimeBehavior=convertToNull</property>
<property name="hibernate.connection.username">xy</property>
<property name="hibernate.connection.password">xy</property>
<property name="hibernate.connection.autocommit">false</property>
<property name="hibernate.show_sql">false</property>
<property name="hibernate.format_sql">false</property>
<property name="hibernate.use_sql_comments">false</property>
<property name="hibernate.query.factory_class">org.hibernate.hql.internal.classic.ClassicQueryTranslatorFactory</property>
<property name="hibernate.connection.provider_class">org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider</property>
<property name="hibernate.c3p0.min_size">5</property>
<property name="hibernate.c3p0.max_size">20</property>
<property name="hibernate.c3p0.timeout">300</property>
<property name="hibernate.c3p0.max_statements">250</property>
<property name="hibernate.c3p0.idle_test_period">3000</property>
<property name="hibernate.jdbc.batch_size">250</property>
<property name="hibernate.connection.release_mode">auto</property>
<property name="hibernate.order_inserts">true</property>
<property name="hibernate.order_updates">true</property>
<property name="hibernate.cache.use_second_level_cache">false</property>
<property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
<property name="hibernate.cache.use_query_cache">true</property>
<property name="net.sf.ehcache.configurationResourceName">hibernate_ehcache.xml</property>
我正在使用:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-c3p0</artifactId>
<version>4.3.5.Final</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.31</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.3.4.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>ejb3-persistence</artifactId>
<version>1.0.2.GA</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
<version>4.3.4.Final</version>
</dependency>
我几乎没有使用 hibernate 的经验,我猜我犯了一个巨大的错误,所以请随时提出任何建议。 我切换到休眠是因为 ORM 功能并且来自普通的 jdbc 准备好的语句,具有极快的性能。 MYSQL-Server 处于良好的配置状态。
编辑1: 我知道: Unnecessary queries in Hibernate - MySql 我的实体中没有事务注释,也没有任何地方定义的隔离级别
编辑2: 我将连接池更改为 bonecp - 问题仍然存在。似乎显然是一个休眠配置问题。
编辑3: 尝试了许多不同的东西,发现可能有一点提示: 如果我每 5 次插入手动设置 session.flush()(=例如批处理的大小)[从休眠中再次尝试批处理示例],则 select @@session.tx_read_only 查询出现双倍 - 每 5 次查询.因此,我假设 select @@session.tx_read_only 与刷新有关。有什么方法可以防止休眠刷新每个插入/更新? 到目前为止,我尝试过: session.setFlushMode(FlushMode.COMMIT/NEVER/etc) 行为没有任何变化。也许我错误地配置了任何东西......休眠触发刷新每个插入是什么?表的唯一约束?休眠验证框架?复杂的对象图?并发难?可能是一个锁定问题(Hibernate 不确定其他人是否锁定了表并且不进行批处理,但如果表是只读的,则检查每个插入?)?
我没有发现任何与这种极端(我假设)潮红行为有关的东西。
【问题讨论】:
标签: java mysql sql hibernate jpa