【发布时间】:2021-08-28 03:50:26
【问题描述】:
我有一个 Spring Boot 应用程序,在这个 REST 调用中调用了一个 REST 服务,完成了两个单独的 DB 操作(正在使用 Spring Data JPA)。第一个更新一些数据库表,第二个从所述表中读取并执行一些操作。
@GetMapping("/process")
public void process(){
service1.updateValues();//updates the values
service2.readValuesAndProcess();//reads those updated values and execute some logic and persist at the end
}
现在的问题是;
第二种方法似乎没有读取在第一种方法中更新的更新值,而是以某种方式读取更新之前的值。这两个方法都是@Transactional,实体是@versioned,当调用保存操作时会抛出ObjectOptimisticLockingFailureException。
在 application.properties 中 spring.jpa.open-in-view 属性为 true,当我将其更改为 false 时,一切都按预期工作,但我不能保证我不会在其他地方得到 lazyInitializationException。
我尝试将事务方法传播更改为 REQUIRES_NEW,但没有任何变化。
【问题讨论】:
-
如何更新 updateValues() 方法中的值?如果您使用 spring.jpa.open-in-view = true,那么在您的请求中,只有一个实体管理器用于您的所有语句。因此,如果您保存的对象仍在实体管理器缓存中,则可能不会从数据库中重新加载它。顺便说一句, spring.jpa.open-in-view = true 被认为是反模式。看到这个:stackoverflow.com/questions/30549489/…
-
是的,我们使用 spring.jpa.open-in-view = true,您的见解是正确的。实体是通过来自另一个实体的@onetoone 关系加载的,并且不会使用 save 进行更新,而是使用自定义 hql 查询进行更新,因此不会更新一级缓存。因此,当执行第二次选择时,将从一级缓存中获取实体。
标签: java spring-boot spring-data-jpa transactions