Java Hibernate和Spring事务管理器:事务未成功启动
我有一个名为saveList()的方法的通用存储库。此方法的目的是获取一个列表,并将其保存在500个对象的“块”中。不幸的是,当我开始提交时,我得到了一个“TransactionException:Transaction not successfully started” 我所看到的一切都表明这是Spring事务管理器的结果。不幸的是,对于这个特定的方法,我需要手动控制事务 相关代码如下:Java Hibernate和Spring事务管理器:事务未成功启动,java,hibernate,spring,Java,Hibernate,Spring,我有一个名为saveList()的方法的通用存储库。此方法的目的是获取一个列表,并将其保存在500个对象的“块”中。不幸的是,当我开始提交时,我得到了一个“TransactionException:Transaction not successfully started” 我所看到的一切都表明这是Spring事务管理器的结果。不幸的是,对于这个特定的方法,我需要手动控制事务 相关代码如下: // from generic non-abstract repository @Transactiona
// 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();
}
//来自通用非抽象存储库
@交易的
公共无效存储列表(列表对象列表){
Session Session=sessionFactory.getCurrentSession();
事务tx=会话.beginTransaction();
int i=1;
对于(对象:对象列表){
session.save(obj);
//sessionFactory.getCurrentSession().save(obj);
i++;
如果(i%500==0){
session.flush();
//sessionFactory.getCurrentSession().flush();
}
}
如果(!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>
非常感谢您的帮助。您正在使用声明式和编程式事务划分。摆脱
会话.beginTransaction()
和相关的方法调用。如果必须使用手动事务,请仅使用@Transactional。然后去掉顶部的声明性@Transactional
选项。我真的不明白这样做的意义,因为在刷新之间不会清除会话(因此需要与在事务结束时让Hibernate刷新一样多的内存),但是,如果您真的想这样做,并且只想为这个方法创建一个新的事务,只需使用
@Transactional(propagation = Propagation.REQUIRES_NEW)
忘记Hibernate事务管理
这将使Spring暂停当前事务(如果有),启动一个新事务,执行您的方法并提交/回滚新事务,然后恢复暂停的事务(如果有)。使用openSession方法获取会话对象,并在您完成工作时关闭它。它将完美地工作。比如说
Session session = sessionFactory.openSession();
好吧,我相信你的话,因为你是多年前在SCE教我春露的那个人。不幸的是,无论我是否使用注释,我都会遇到同样的错误。嗯。。。杰森。。。弗格森?小世界,嗯?“Transaction not successfully started”(事务未成功启动)错误来自hibernate,当您尝试提交未启动或已提交/回滚的事务时。正如最初发布的一样,您的手册
tx.commit()
之后会有另一次提交,这是@Transactional的结果。您仍然必须以某种方式提交事务两次。哦,顺便说一句,session.flush()
不会“持久化”任何内容。它只是强制hibernate向数据库发出语句。我发现,在我的应用程序上下文中,我有一个建议类中的所有内容(从技术上讲,是它实现的接口中的所有内容)。我注释掉了应用的,但现在我得到了一个意外的回滚异常:事务回滚,因为它已被标记为仅回滚。这通常发生在您尝试提交已被标记为回滚的事务时,可能是因为引发了异常。我已删除对session.clear()的调用出于某种原因,谢谢你提醒我把它放回去。