Пакетные вставки с помощью Hibernate и Spring

Мое приложение основано на 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) в базе данных. Теперь метод сохранения вызывается в цикле из функции разбора. Теперь проблема в том, что примерно после 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(). Я не уверен, должен ли я выполнять управление транзакциями для этого метода сохранения отдельно в DAO, помещая @Transactional(readOnly=false, PROPOGATION=NEW)на save(), или этот подход хорошо?

Также я обновил hibernate.jdbc.batch_sizeдо 20 в файле конфигурации hibernate.cfg.

Есть предложения?

5
задан Brian Tompsett - 汤莱恩 30 December 2014 в 19:37
поделиться