我们最近从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);
答案 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,更多的前沿但包含所有相同的改进和修复过。