comment augmenter les performances des insertions à l'aide de session de l'usine
Je suis en utilisant jpa hibernate à l'aide de couture. Ineed à insérer 200 000 enregistrements à la fois.
Voici mon code:
hibernate.cfg.xml
<hibernate-configuration>
<session-factory name="java:/mobeeSessionFactory">
<property name="hibernate.connection.pool_size">10</property>
<property name="hibernate.connection.driver_class">oracle.jdbc.OracleDriver</property>
<property name="hibernate.connection.url">jdbc:oracle:thin:@localhost:1521:mobee</property>
<property name="hibernate.connection.username">mobeemigrate</property>
<property name="hibernate.connection.password">mobeemigrate</property>
<property name="hibernate.show_sql">false</property>
<property name="hibernate.dialect">org.hibernate.dialect.OracleDialect</property>
<property name="hibernate.format_sql">false</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<property name="hibernate.session_factory_name">java:/mobeeSessionFactory</property>
<property name="hibernate.connection.datasource">mobeeadminDataSource</property>
<property name="hibernate.jdbc.batch_size">10000</property>
<property name="hibernate.cache.use_first_level_cache">true</property>
<property name="hibernate.cache.use_second_level_cache">false</property>
<property name="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.JBossTransactionManagerLookup</property>
<property name="hibernate.transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</property>
<property name="hibernate.transaction.auto_close_session">false</property>
<property name="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>
<property name="hibernate.transaction.flush_before_completion">true</property>
<!-- Here are the mappings -->
<mapping package="com.manam.mobee.persist.entity"/>
<mapping class="com.manam.mobee.persist.entity.TempCustomers"/>
<mapping class="com.manam.mobee.persist.entity.TempAccounts"/>
</session-factory>
component.xml
<persistence:hibernate-session-factory name="hibernateSessionFactory" cfg-resource-name="hibernate.cfg.xml"/>
<persistence:managed-hibernate-session name="session"
auto-create="true"
session-factory-jndi-name="java:/mobeeSessionFactory"/>
Exemple De Code:
Session session =hibernateSessionFactory.openSession();
Transaction tx = session.beginTransaction();
for(int i=0;i<doTempAccounts.size();i++){
try {
TempAccounts temp=new TempAccounts();
BeanUtils.copyProperties(temp, doTempAccounts.get(i));
session.save(temp);
if ( i % 10000 == 0 ) { //10000, same as the JDBC batch size
//flush a batch of inserts and release memory:
log.info("********** Batch Updates**********");
session.flush();
session.clear();
}
}
}
tx.commit();
session.close();
Le code ci-dessus fonctionne, mais il faut environ 10 minutes pour insérer 200 000 enregistrements. Est-il de la configuration de mon code pour augmenter le rendement des insertions?
Dans le code ci-dessus, je fais une session.flush() tous les 10000 enregistrements mais ses pas insérer une Base de données à chaque fois. Pouvez-vous expliquer comment effectuer des insertions dans la base de données.?
- regarder dans stateless session pour les opérations en bloc
- Merci pour la réponse ,je vais aller à travers elle,j'ai un doute dans cette session, j'ai soit au niveau de la db dans tous les 10000 record, mais pourquoi il n'a pas l'insérer dans la base de données à chaque fois?
Vous devez vous connecter pour publier un commentaire.
Regarder dans statelesssession n', et comment l'utiliser pour insérer des éléments dans votre DB. Cela semble être le go de répondre lorsque cette question est posée et j'ai personnellement utilisé pour faire un 15 minutes de travail complet en environ 15 secondes. Il ne convient pas à tous les scénarios, mais s'il le fait, il fonctionne très bien.
Je présume que tu veux dire que les dossiers ne semblent pas être là jusqu'à ce que vous atteignez la fin; c'est à dire qu'ils ne sont pas dans une requête faite dans une autre transaction.
Si c'est ce que vous voulez dire, alors l'explication est simple. Vous faites de l'insérer dans une transaction unique, et seuls les résultats deviennent visibles lorsque la transaction est validée ... à la fin. Essayez de diviser les inserts en plusieurs transactions si vous en avez besoin pour être visible plus tôt.
Vous devriez également lire la documentation Hibernate sur les opérations par lots - http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/batch.html. Je note qu'il est dit qu'un raisonnable la taille des lots est de 20 à 50 ... pas 10000. Il mentionne également les approches de l'aide de SQL directement pour le lot de données des opérations et
StatelessSession
.Voici une autre ressource qui est spécifique à l'insertion et comprend l'insertion avec
StatelessSession
: http://javainnovations.blogspot.com.au/2008/07/batch-insertion-in-hibernate.htmlVous pouvez le faire presque la même façon de faire en SQL. Regardez les suivantes HQL exemple:
Référence: http://docs.jboss.org/hibernate/orm/4.0/devguide/en-US/html/ch04.html#d0e2184