我的应用程序基于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。
有什么建议吗?