Мое приложение основано на Hibernate 3.2 и Spring 2.5. Вот руководство сделки, связанное с сниппают контекста приложения:Пакетные вставки с гибернатом и весной
<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 вызывает другой метод: «save()» в том же DAO, который хранит большое количество строк (около 5000) в базе данных. Теперь метод save вызывается в цикле из функции синтаксического анализа. Теперь проблема в том, что после примерно 100 вызовов метода «save». Иногда я получаю исключение 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()
. Я не уверен, должен ли я выполнять управление транзакциями для этого метода сохранения отдельно в DAO, разместив @Transactional(readOnly=false, PROPOGATION=NEW)
по адресу save()
, или этот подход в порядке?
Также я обновил hibernate.jdbc.batch_size
до 20 в конфигурационном файле hibernate.cfg.
Любые предложения?