Java 使用@Transactional属性手动提交
我使用spring+hibernate模板来处理实体。有相当多的实体需要一次加载,所以我从hibernate模板中检索了一个迭代器 每个实体都应作为单个工作单元进行处理。我试图将实体处理放在一个单独的事务中(传播=必需\新)。然而,我以一个例外结束,声明代理绑定到两个会话。这是由于用于迭代器延迟加载的挂起事务造成的。对于延迟加载和处理实体,我使用相同的bean。(可能应该将其重构为两个单独的DAO:一个用于延迟加载,另一个用于处理?) 然后,我尝试使用在处理每个实体之后提交的单个事务。这里更好的是,在实体处理期间并没有异常,但在处理完成并且方法返回之后,从spring事务管理代码中抛出异常Java 使用@Transactional属性手动提交,java,spring,hibernate,Java,Spring,Hibernate,我使用spring+hibernate模板来处理实体。有相当多的实体需要一次加载,所以我从hibernate模板中检索了一个迭代器 每个实体都应作为单个工作单元进行处理。我试图将实体处理放在一个单独的事务中(传播=必需\新)。然而,我以一个例外结束,声明代理绑定到两个会话。这是由于用于迭代器延迟加载的挂起事务造成的。对于延迟加载和处理实体,我使用相同的bean。(可能应该将其重构为两个单独的DAO:一个用于延迟加载,另一个用于处理?) 然后,我尝试使用在处理每个实体之后提交的单个事务。这里更好的
@Transactional
public void processManyManyEntities() {
org.hibernate.Sesstion hibernateSession = myDao.getHibernateTemplate().getSessionFactory().getCurrentSession();
Iterator<Entity> entities = myDao.findEntitesForProcessing();
while (entities.hasNext()) {
Entity entity = entities.next();
hibernateSession.beginTransaction();
anotherBean.processSingleEntity(entity);
hibernateSession.getTransaction().commit();
}
}
@Transactional
public void processManyManyEntities(){
org.hibernate.Sesstion hibernateSession=myDao.getHibernateTemplate().getSessionFactory().getCurrentSession();
迭代器实体=myDao.findentialsforprocessing();
while(entities.hasNext()){
实体=实体。下一步();
hibernateSession.beginTransaction();
processSingleEntity(实体);
hibernateSession.getTransaction().commit();
}
}
processSingleEntity
是另一个bean中的一个方法,用@Transactional
注释,因此所有实体都有一个事务。我检查了导致异常的事务:这是从hibernateSession.beginTransaction()
返回的第一个事务,所以它没有在事务管理器中更新
有几个问题:
不重构dao就可以避免会话绑定异常吗?这与问题无关,因为问题在于会话和休眠,而不是dao
是否可以在事务管理器中更新事务已解决
是否可以使用相同的事务(对于另一个Bean.processSingleEntity(entity);)而不使用
processManyManyEntities
上的@Transactional
注释?我更愿意删除“processManyManyEntities()”上的@Transactional注释,并急切地从“FindentialsForProcessing”加载所有数据
如果您希望“processSingleEntity”中的每个数据实体都是事务性的,“processSingleEntity”中的@Transactinoal就可以了。您不必在“processManyManyEntities()”上注释@Transactional。但在延迟加载的情况下,急切加载是防止源数据加载到另一个会话(例如“processSingleEntity”)中的必要手段
由于每个数据实体都有事务,因此加载源数据时的事务边界不是事务的情况。不要让“延迟加载”使您修改数据的事务意图复杂化。这可以在事务管理器中更新事务。您只需从TransactionSynchronizationManager.getResource(sessionFactory)获取SessionHolder实例,并将会话持有者中的事务设置为当前事务。这使得在必要时提交事务成为可能,并允许spring事务管理器在方法返回后提交事务。我无法避免延迟加载,我有数千个实体。也许您可以尝试一次处理两个条目,并进行快速加载。但如果你能描述更多关于“findEntitesForProcessing”的细节,那就更清楚了。“processSingleEntity”内部的实体将处理多少数据。幸运的是,有一种方法可以在事务管理器中更新事务。我补充了一个详细的答案。急切地加载多个实体是个好主意!如果什么也没找到,我会用它的!:)有可能举个例子吗?解决方案不是很清楚,但似乎很有趣。