我的應用程序基於Hibernate 3.2和Spring 2.5。下面是從應用程序上下文相關的片段中,交易管理:使用Hibernate和Spring批量插入
<tx:annotation-driven transaction-manager="txManager"/>
<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
<property name="nestedTransactionAllowed" value="true"/>
</bean>
<bean id="transactionTemplate" classs="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager" ref="txManager"/>
</bean>
<bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor"/>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="configLocation" value="classpath:/hibernate.cfg.xml"></property>
</bean>
對於所有的DAO的有相關的服務類和交易是在服務層中的每個方法使用@Transactional
處理那裏。然而,現在有一種情況是DAO中的一個方法從服務層調用「parse()」。在我指定的服務層@Transactional(readOnly=false)
中。 DAO中的這種解析方法在存儲大量行(大約5000)到數據庫中的同一DAO中調用另一種方法「save()」。現在,從解析函數的循環中調用save方法。現在的問題是,大約100次調用「保存」方法後..我有時得到一個OutOfMemory異常或有時程序停止響應。
現在這些是我對保存方法所做的更改:
Session session = getHibernateTemplate().getSessionFactory().openSession();
Transaction tx = session.beginTransaction();
int counter = 0;
if(books!=null && !books.isEmpty()){
for (Iterator iterator = books.iterator(); iterator
.hasNext();) {
Book book = (Book) iterator.next();
session.save(book);
counter++;
if(counter % 20==0) {
session.flush();
session.clear();
}
}
}
tx.commit();
session.close();
這是在我的應用程序的唯一方法,我開始交易像這樣,在方法的最後提交。否則我通常只需撥打getHibernateTemplate.save()
。我不確定我是否應該通過將@Transactional(readOnly=false, PROPOGATION=NEW)
放置在save()
上單獨在DAO中對此保存方法執行事務管理,或者這種方法是否可行?
此外,我已經在hibernate.cfg配置文件中將hibernate.jdbc.batch_size
更新爲20。
有什麼建議嗎?