我有一个不处理事务(无提交、回滚)的存储过程,我从这样的方法调用它:
@Transactional
void work(Long id) {
var entity = (id == null) ? create() || fetch(id);
process(entity);
repository.callProcedure(id);
}
此代码对于现有实体运行良好,但对于新创建的实体则失败。看来Oracle 过程没有看到未提交的数据。我相信该过程应共享相同的事务,因此它实际上可以看到未提交的数据。我希望有一个事务,因此如果过程失败,Spring 将回滚在 Java 和过程中所做的更改。
根据您对我上面评论的回答(刷新是一种解决方法,为什么需要它),我认为它有帮助。您没有分享您的代码,但我认为
create
会执行以下操作:
entityManager.persist(myNewEntity);
这会在内存中创建实体,并最终在数据库中创建它,但没有什么可以强制 JPA 立即执行插入。一般来说,JPA 将等到提交、手动刷新或在查询之前发出自动刷新(其中 JPA 知道需要刷新才能获得正确的结果)。
当您在 JPA 之外进行自己的数据库查询/更新时,您首先需要刷新所有挂起的更改。这就是flush的用途。
不要刷新“以防万一”,因为它会损害性能,但在这种情况下,您知道您有过程需要查看的待处理更改(您刚刚创建了实体)。在这种情况下,冲洗就是正确的选择。