Hibernate和Spring事务管理器:事务未成功启动

时间:2011-08-19 15:23:00

标签: java hibernate spring

我有一个Generic Repository,其方法名为saveList()。此方法的目的是获取一个List并将其保存在500个对象的“块”中。不幸的是,当我进入提交时,我收到了“TransactionException:Transaction not successfully successfully”。

我见过的所有内容都说这是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 个答案:

答案 0 :(得分:4)

您正在使用声明式和程序式事务划分。摆脱session.beginTransaction()和相关的方法调用。只使用@Transactional。

答案 1 :(得分:2)

使用openSession方法获取会话对象,并在完成工作后关闭它。它会很完美。例如

Session session = sessionFactory.openSession();

答案 2 :(得分:1)

如果您必须使用手动交易,那么请删除顶部的声明性@Transactional选项。

答案 3 :(得分:1)

我真的没有看到这样做的意义,因为在刷新之间没有清除会话(并且因此需要尽可能多的内存,就好像你在事务结束时让Hibernate刷新一样),但如果你真的想要这样做,只想为这个方法创建一个新的事务,只需用

注释方法
@Transactional(propagation = Propagation.REQUIRES_NEW)

忘了Hibernate事务管理。

这将使Spring暂停当前事务(如果有),启动新事务,执行方法并提交/回滚新事务,然后恢复暂停事务(如果有)。