【发布时间】:2012-03-31 21:02:43
【问题描述】:
我的应用程序基于 Hibernate 3.2 和 Spring 2.5。下面是应用上下文中事务管理相关的sn-p:
<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 中的这个解析方法调用了同一个 DAO 中的另一个方法“save()”,它在数据库中存储了大量行(大约 5000 行)。现在从 parse 函数循环调用 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。
有什么建议吗?
【问题讨论】:
标签: java spring hibernate spring-batch insertion