一个Spring Data (JPA) Repository是线程安全的吗?(也就是说,SimpleJpaRepository是线程安全的吗)

11

我正在使用一个Spring Data(JPA)存储库来处理CRUD样板。

我的存储库接口定义如下:

import org.springframework.data.repository.CrudRepository;

public interface FooRepository extends CrudRepository<Foo, Long>
{
  public Foo findByXAndYAndZ(X x, Y y, Z z);
}

然后Spring会自动地为我生成该接口的实现。我们得到的是一个代理对象,但我相信最终我们会使用 org.springframework.data.jpa.repository.support.SimpleJpaRepository

JdkDynamicAopProxy 是线程安全的, 如果 底层目标类也是线程安全的。因此问题是: SimpleJpaRepository 是线程安全的吗?

3个回答

10
通常来说是这样的。它假设了一个管理的EntityManager,我们可以从Spring的工厂类中获取(如果你正在使用Spring作为容器),或者作为CDI管理的bean(通过@Producer方法声明)。

嗨,Oliver - 謝謝你。我能問一下嗎 - 這個有文檔記錄嗎?你有參考資料嗎? - Greg Kopff
你能详细说明为什么这个“managed” EntityManager 使得 SimpleJpaRepository 线程安全吗? - Greg Kopff
3
我认为这是JPA中EntityManager行为规范的简单结果。默认情况下,它不是线程安全的,因此需要进行管理(即:正确地绑定到线程并代理以指向线程绑定的实例)。在Spring中,通过使用SharedEntityManagerCreator来实现。在CDI的情况下,容器会为您完成这项工作。 - Oliver Drotbohm
Oliver,你有使用SharedEntityManagerCreator的示例吗,就像你建议的那样? - Shantanu Wagh

2

嗨,Tim - 我在那篇文章中没有找到有关线程安全的任何信息。我错过了吗? - Greg Kopff
“Spring wired objects”是什么意思?如果我在Web应用程序上下文中创建一个类并定义一个bean,那么该bean默认为单例,但不是线程安全的。我应该自己处理该bean的线程安全性,即使它被装配了,Spring也不会管理该bean的线程安全性。 - Chrisma Andhika

0

我还不确定,但我认为在特定情况下存储库不是线程安全的。请看:

在github上的spring-data-commons中有一个RepositoryFactorySupport.QueryExecutorMethodInterceptor。

其中包含一个并发哈希映射,其中方法指向查询。如果这些查询包含状态,或者这些查询的任何属性包含状态,则存储库将不再是线程安全的。一个很好的例子是spring-data-neo4j。DerivedGraphRepositoryQuery具有问题,因为它包含CypherFinderQuery。这些查询包含参数形式的状态。我相信在DerivedGraphRepository中的查询期间,可能会出现参数被另一个线程覆盖的竞争条件。如果查询对象的作者赋予它们状态,则在其他spring数据存储库中也可能发生这种情况。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接