Hibernate 4需要超过1分钟来持续80MB blob

时间:2014-08-01 10:01:47

标签: java hibernate jpa jboss

我们最近从JBoss 6 迁移到JBoss 7.1.1 ,因此从hibernate 3.6.6 切换到hibernate 4.0 .1 并在将blob数据存储到数据库时遇到问题。 使用hibernate 3,持续约80MB的blob花费不到10秒,但是使用hibernate 4,持续时间超过1分钟。我已经尝试了几个版本的hibernate 4 - 4.0.x,4.1.x,4.2.x,行为是一样的。

环境:

jboss 7.1.1,hibernate 4.0.1,ojdbc6,Oracle DB 11.2.0.3.0 - > 1分钟
jboss 6.1.0,hibernate 3.6.6,ojdbc6,Oracle DB 11.2.0.3.0 - ~10秒

我还打开了记录到TRACE级别以查看消耗时间的位置并找到以下内容:

17:33:58,203 TRACE [org.hibernate.engine.spi.ActionQueue] Adding an EntityInsertAction for [x.x.datastore.persistence.LobDataOutEntity] object
17:33:58,204 TRACE [org.hibernate.engine.spi.ActionQueue] Adding insert with no non-nullable, transient entities: [EntityInsertAction[x.x.datastore.persistence.LobDataOutEntity#2972533]]
17:33:58,205 TRACE [org.hibernate.engine.spi.ActionQueue] Adding resolved non-early insert action.
17:33:58,206 TRACE [org.hibernate.action.internal.UnresolvedEntityInsertActions] No unresolved entity inserts that depended on [[x.x.datastore.persistence.LobDataOutEntity#2972533]]
**17:33:58,206 TRACE [org.hibernate.action.internal.UnresolvedEntityInsertActions] No entity insert actions have non-nullable, transient entity dependencies.
17:34:21,162 TRACE [org.hibernate.event.internal.AbstractFlushingEventListener]  Flushing session**
17:34:21,163 DEBUG [org.hibernate.event.internal.AbstractFlushingEventListener]  Processing flush-time cascades
17:34:21,163 TRACE [org.hibernate.engine.internal.Cascade] Processing cascade ACTION_PERSIST_ON_FLUSH for: x.x.datastore.persistence.LobDataOutEntity
17:34:21,164 TRACE [org.hibernate.engine.internal.Cascade] Done processing cascade ACTION_PERSIST_ON_FLUSH for: x.x.datastore.persistence.LobDataOutEntity
17:34:21,189 TRACE [org.hibernate.persister.entity.AbstractEntityPersister] Dehydrating entity: [x.x.datastore.persistence.LobDataOutEntity#2972533]
17:34:21,189 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] binding parameter [1] as [BIGINT] - 2972533
17:34:21,190 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] binding parameter [2] as [BLOB] - oracle.sql.BLOB@67c6db48
17:34:48,845 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] binding parameter [3] as [CLOB] - <null>
**17:34:48,846 DEBUG [org.hibernate.engine.jdbc.batch.internal.BatchingBatch] Executing batch size: 1
17:35:21,295 DEBUG [org.hibernate.jdbc.Expectations] Success of batch update unknown: 0**
17:35:21,295 TRACE [org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl] Releasing statement [org.jboss.jca.adapters.jdbc.jdk6.WrappedPreparedStatementJDK6@52cc5b6]
17:35:21,296 TRACE [org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl] Closing prepared statement [org.jboss.jca.adapters.jdbc.jdk6.WrappedPreparedStatementJDK6@52cc5b6]
17:35:21,297 TRACE [org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl] Starting after statement execution processing [AFTER_STATEMENT]
17:35:21,297 DEBUG [org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl] Skipping aggressive release due to manual disabling
17:35:21,298 TRACE [org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl] Starting after statement execution processing [AFTER_STATEMENT]
17:35:21,299 DEBUG [org.hibernate.engine.jdbc.internal.LogicalConnectionImpl] Releasing JDBC connection
17:35:21,299 DEBUG [org.hibernate.engine.jdbc.internal.LogicalConnectionImpl] Released JDBC connection
17:35:21,300 TRACE [org.hibernate.event.internal.AbstractFlushingEventListener] Post flush

从上面的跟踪日志中,当参数绑定到查询以及执行的刷新部分中的某个位置时,时间似乎相加。 hibernate 4中会发生什么变化导致这种延迟?

有没有人可以给我更多见解?非常感谢你的帮助:)

我在下面添加了我的配置和源代码。

#的persistence.xml

<persistence xmlns="http://java.sun.com/xml/ns/persistence">
  <persistence-unit name="DAL-connector-persistence">
  <description>Persistence unit for SyncML module</description>
  <provider>org.hibernate.ejb.HibernatePersistence</provider>
  <jta-data-source>java:jboss/datasources/DS</jta-data-source>
  <properties>
      <property name="hibernate.dialect" value="org.hibernate.dialect.CustomOracleDialect"/> //the custom dialect is built over Oracle10gDialect
      <property name="hibernate.connection.release_mode" value="auto"></property>
      <property name="hibernate.transaction.auto_close_session" value="true"></property>
      <property name="hibernate.show_sql" value="false"></property>
      <property name="hibernate.jdbc.batch_size" value="30"></property>
      <property name="hibernate.jdbc.fetch_size" value="30"></property>
      <property name="hibernate.cache.use_second_level_cache" value="false"></property>
      <property name="hibernate.cache.use_query_cache" value="false"></property>
      <property name="hibernate.current_session_context_class" value="jta"></property>
      <property name="hibernate.transaction.flush_before_completion" value="true">  </property>
    </properties>
</persistence-unit>

#DS定义

<xa-datasource jndi-name="java:jboss/datasources/****DS" pool-name="***LDS" enabled="true" use-java-context="true">
   <xa-datasource-property name="URL">jdbc:oracle:thin:@@oracle.ds.ip@:@oracle.ds.sid@</xa-datasource-property>
   <xa-datasource-class>oracle.jdbc.xa.client.OracleXADataSource</xa-datasource-class>
   <driver>oracle</driver>
   <transaction-isolation>TRANSACTION_READ_COMMITTED</transaction-isolation>
   <xa-pool>
       <min-pool-size>5</min-pool-size>
       <max-pool-size>20</max-pool-size>
       <prefill>true</prefill>
       <is-same-rm-override>false</is-same-rm-override>
   </xa-pool>
   <security>
       <security-domain>***DS-oracle-encrypted-password</security-domain>
   </security>
   <recovery no-recovery="true"/>
   <validation>
       <validate-on-match>false</validate-on-match>
       <background-validation>true</background-validation>
       <exception-sorter class-name="org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter"/>
   </validation>
   <timeout>
       <blocking-timeout-millis>5000</blocking-timeout-millis>
       <idle-timeout-minutes>2</idle-timeout-minutes>
   </timeout>
   <statement>
       <track-statements>true</track-statements>
       <prepared-statement-cache-size>1000</prepared-statement-cache-size>
   </statement>
</xa-datasource>

#Java代码

//lob initialization
LobDataOutEntity lobEntity = new LobDataOutEntity(); 
Session session = (Session) manager.getDelegate(); 
Blob newContent = Hibernate.getLobCreator(session).createBlob(new byte[]{}); 
lobEntity.setBlobData(newContent); 
manager.persist(lobEntity);


//read chunks of bytes and write them into the blob
while (...)
{
  lobEntity.getBlobData().setBytes(wrote + 1, b64DataBuf);
}

//merge the content when all bytes have been written into the blob
manager.merge(lobEntity);

1 个答案:

答案 0 :(得分:0)

更新Hibernate,自版本4.0.x起,应用了许多与Blob存储相关的重大改进(以及更多)。 以版本4.2.15.Final或 - 如果你准备好了JPA 2.1 - 版本4.3.6.Final,这些是写这篇文章时最稳定和最有效的版本。

我希望这些最新版本的性能也超过旧的3.6.x版本,如果我错了,请告诉我们project JIRA的更多详细信息。

另外,为什么你今天要升级到JBoss 7.1?它已经过时且没有维护。您现在可以download the latest Red Hat JBoss Enterprise Application Platform - 免费用于开发目的,它基于JBoss 7. +但包括数千个错误修正和改进,或get the latest version of WildFly,更多的前沿但包含所有相同的改进和修复过。