我有一个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>
感谢任何帮助。
答案 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暂停当前事务(如果有),启动新事务,执行方法并提交/回滚新事务,然后恢复暂停事务(如果有)。