【问题标题】:How to get the saved entity from session in a new but nested transaction (Propagation.REQUIRES_NEW)如何在新但嵌套的事务中从会话中获取保存的实体(Propagation.REQUIRES_NEW)
【发布时间】:2016-05-06 09:17:49
【问题描述】:

我有一个要求,我需要我的嵌套事务是一个新事务,以便只有当前事务会在出现异常的情况下回滚,而不是调用者,并且我还想在嵌套事务中获取保存的实体,这些实体保存在上层事务。

@Transactional(readOnly = false, isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public void A(){
//saving  entity x
B();
}

@Transactional(readOnly = false, isolation = Isolation.DEFAULT, propagation = **Propagation.REQUIRES_NEW**, rollbackFor = Exception.class)
public void B(){
//saving some other entity
//fetch previously created entity x

}

现在的问题是当我尝试获取保存在 A() 中的 B() 中的实体 x 时,我没有得到这个。

但是,如果我将 B() 的 事务类型从 Propagation.REQUIRES_NEW 更改为 Propagation.REQUIRED,它就可以工作。这种情况下的问题是,如果事务 B 回滚,事务 A 也会回滚,但这不是故意的。 请提出一些可以解决这两个用例的解决方案。

【问题讨论】:

    标签: database spring hibernate jpa spring-transactions


    【解决方案1】:

    执行B() 时,您的A() 事务不会提交。 因此,在获取B() 中的元素时,您将仅获得已保存在数据库中的内容。那时您的实体 x 不存在。

    第一个问题是:为什么需要在B() 中获取实体 x? 第二个问题是:如果您需要B() 中的实体 x,您不能将其作为参数传递吗?

    【讨论】:

    • 我正在使用 JPA 实体管理器来持久化实体所以即使它没有在数据库中提交,它也应该从会话中检索。我不能将实体作为参数传递,因为我没有直接在 B() 中使用这个实体,而是运行一个 SQL 查询,它的连接很少,它将根据以前保存的实体获取数据。
    • 如果是Propagation.REQUIRED,它将从会话中检索...或者您必须按照此答案中的指定更改隔离级别:stackoverflow.com/questions/8490852/…
    • 只是为了更精确:REQUIRES_NEW 不想从“旧”上下文中知道任何内容,因此它创建一个具有新休眠会话的新实体管理器......将“旧”一个留在打开状态,直到它被提交。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-07
    • 2017-05-03
    • 1970-01-01
    • 2015-04-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多