【问题标题】:Is a Spring Data (JPA) Repository thread-safe? (aka is SimpleJpaRepository thread safe)Spring Data (JPA) Repository 是线程安全的吗? (又名 SimpleJpaRepository 线程安全)
【发布时间】:2013-04-04 15:34:16
【问题描述】:

我正在使用 Spring Data (JPA) repository 来处理 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 线程安全吗?

【问题讨论】:

    标签: java jpa spring-data spring-data-jpa


    【解决方案1】:

    一般来说,是的。它假设一个托管的EntityManager,我们将从 Spring 的工厂类(如果您使用 Spring 作为容器)或作为 CDI 托管 bean(通过 @Producer 方法声明)获得。

    【讨论】:

    • 嗨奥利弗 - 谢谢。我可以问一下 - 这是否记录在某处?你有参考吗?
    • 你能详细说明为什么这个“托管”EntityManager 使SimpleJpaRepository 线程安全吗?
    • 我认为这是在 JPA 中指定 EntityManager 行为方式的简单结果。默认情况下它不是线程安全的,因此需要对其进行管理(阅读:正确绑定到线程并代理指向线程绑定实例)。在 Spring 中,这是通过使用 SharedEntityManagerCreator 来实现的。在 CDI 的情况下,容器会为你做这件事。
    • Oliver,你有像你建议的那样使用 SharedEntityManagerCreator 的例子吗?
    【解决方案2】:

    【讨论】:

    • 嗨 Tim - 我在 that article 中没有找到任何关于线程安全的信息。我错过了吗?
    • “弹簧连线对象”是什么意思?如果我创建一个类并在 Web 应用程序上下文中定义该类的一个 bean,那么该 bean 默认情况下是一个非线程安全的单例。我应该自己处理那个 bean 的线程安全,即使它是有线的,Spring 也不会管理 bean 的线程安全。
    【解决方案3】:

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

    github 上 spring-data-commons 中的 RepositoryFactorySupport.QueryExecutorMethodInterceptor。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-10-19
      • 1970-01-01
      • 2021-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多