Диспетчер транзакций Hibernate и Spring: транзакция не была успешно запущена - PullRequest
0 голосов
/ 19 августа 2011

У меня есть общий репозиторий с методом с именем saveList ().Цель этого метода - взять список и сохранить его в виде «кусочков» из 500 объектов.К сожалению, я получаю «TransactionException: транзакция не была успешно запущена», когда я получаю коммит.

Все, что я видел, говорит о том, что это результат Spring Transaction Manager.К сожалению, для этого конкретного метода мне нужно вручную управлять транзакцией.

Соответствующий код ниже:

// from generic non-abstract repository
@Transactional
public void saveList(List<T> objectList) {
    Session session = sessionFactory.getCurrentSession();
    Transaction tx = session.beginTransaction();
    int i = 1;
    for (T obj : objectList) {

        session.save(obj);
        //sessionFactory.getCurrentSession().save(obj);
        i++;
        if (i % 500 == 0) {
            session.flush();
            //sessionFactory.getCurrentSession().flush();
        }
    }
    if (!tx.wasCommitted()) {
        tx.commit();
    }
    //sessionFactory.getCurrentSession().getTransaction().commit();
}

Конфигурация из applicationContext.xml:

<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>

Любая помощь приветствуется.

Ответы [ 4 ]

4 голосов
/ 19 августа 2011

Вы используете как декларативное, так и программное разграничение транзакций. Избавьтесь от session.beginTransaction() и связанных вызовов методов. Используйте только @ Transactional.

2 голосов
/ 19 июня 2014

Используйте метод openSession, чтобы получить объект сеанса и закрыть его, когда вы закончите свою работу. Это будет работать отлично. Например

Session session = sessionFactory.openSession();
1 голос
/ 19 августа 2011

Я на самом деле не вижу смысла делать это, так как сессия не очищается между сбросами (и, таким образом, потребуется столько памяти, как если бы вы позволяли Hibernate сбрасываться в конце транзакции), но если вы действительнохотите сделать это и просто хотите новую транзакцию только для этого метода, просто аннотируйте метод с помощью

@Transactional(propagation = Propagation.REQUIRES_NEW)

и забудьте об управлении транзакциями в Hibernate.

Это заставит Spring приостановитьтекущей транзакции (если есть), запустите новую транзакцию, выполните свой метод и подтвердите / откатите новую транзакцию, а затем возобновите приостановленную транзакцию (если есть).

1 голос
/ 19 августа 2011

Если вам нужно использовать транзакцию вручную, то избавьтесь от декларативной опции @Transactional вверху.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...