【问题标题】:manual commits with @Transactional attribute带有@Transactional 属性的手动提交
【发布时间】:2012-03-12 01:40:52
【问题描述】:

我使用spring+hibernate模板来处理实体。一次加载的实体数量相当多,所以我从休眠模板中检索了一个迭代器。

每个实体都应该作为一个单独的工作单元来处理。我试图将实体处理放在一个单独的事务中(传播 = REQUIRED_NEW)。但是,我以异常结束,指出代理绑定到两个会话。这是由于用于迭代器延迟加载的暂停事务。我使用相同的 bean 进行延迟加载和处理实体。 (也许应该重构为两个独立的 daos:一个用于延迟加载,一个用于处理?)

然后我尝试使用在处理每个实体后提交的单个事务。这里好多了,实体处理过程中没有异常,但是处理完成,方法返回后,spring事务管理代码会抛出异常。

@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();
    }
}

processSingleEntity 是另一个用@Transactional 注释的bean 中的方法,因此所有实体都有一个事务。我检查了导致异常的事务:它是从hibernateSession.beginTransaction() 返回的第一个事务,所以它只是没有在事务管理器中更新。

有几个问题:

是否可以在不重构 dao 的情况下避免会话绑定异常?这不是相关问题,因为问题在于 Session 和休眠而不是 dao

是否可以在事务管理器中更新事务? 已解决

是否可以在processManyManyEntities 上使用没有@Transactional 注释的相同事务(对于anotherBean.processSingleEntity(entity);)?

【问题讨论】:

    标签: java spring hibernate


    【解决方案1】:

    我宁愿删除“processManyManyEntities()”上的@Transactional 注释,并且急切地从“findEntitesForProcessing”加载所有数据。

    如果您希望每个数据实体在“processSingleEntity”中都是事务性的,那么“processSingleEntity”上的@Transactinoal 就可以了。您不必在“processManyManyEntities()”上注释 @Transactional。但是在延迟加载的情况下,急切加载是防止源数据在另一个会话中加载的必要手段,例如在“processSingleEntity”中。

    由于每个数据实体的事务,加载源数据的事务边界不是您的事务的情况。不要让“延迟加载”使您修改数据的事务意图复杂化。

    【讨论】:

    • 我无法避免延迟加载,我有成千上万的实体。
    • 也许您可以尝试一次处理几个条目,使用急切加载。但是如果你能描述更多关于“findEntitesForProcessing”的细节会更清楚。 “processSingleEntity”内部的实体将处理多少数据。
    • 幸运的是,有一种方法可以在事务管理器中更新事务。我添加了一个详细的答案。急切地加载几个实体的好主意!如果什么都没找到,我会使用它! :)
    【解决方案2】:

    可以在事务管理器中更新事务。您需要做的就是从TransactionSynchronizationManager.getResource(sessionFactory) 获取 SessionHolder 实例并将会话持有者中的事务设置为当前。这样可以在必要时提交事务,并允许在方法返回后由 Spring 事务管理器提交事务。

    【讨论】:

    • 可以举个例子吗?解决方案不是很清楚,但看起来很有趣。
    猜你喜欢
    • 1970-01-01
    • 2014-08-11
    • 2019-03-28
    • 2013-04-24
    • 1970-01-01
    • 2021-03-26
    • 1970-01-01
    • 1970-01-01
    • 2020-03-25
    相关资源
    最近更新 更多