Spring:@PersistenceContext和@Autowired线程安全?

ber*_*tie 6 spring jpa jpa-2.0

基于这个例子:

@Service
public class Purchase {
  @PersistenceContext
  private EntityManager em;

  @Autowired
  private PurchaseDAO dao;

  private String normalField;

  .... // methods, operations, etc
}
Run Code Online (Sandbox Code Playgroud)

如果我错了,请帮助纠正我:

  1. 服务类PurchasePurchaseDAO是由spring管理的单例
  2. 服务类的字段normalField不是线程安全的,因为singleton是许多人共享的单个对象
  3. 让我们假设@ Repository-annotated-PurchaseDAO没有任何字段,这意味着它的线程安全,将由spring自动注入
  4. EntityManager的实例也是一个线程安全的属性,因为@PersistenceContext将确保当前事务的实体管理器将被使用.

谢谢 !

esa*_*saj 8

  1. 它们默认是单例(当它们是Spring管理的时候),除非你已经配置了它们(从xml配置或注释你可以使用@Scope设置它).
  2. 是的,不是.是的,在多个线程可以同时访问和修改它的意义上它不安全,并且不是因为它取决于数据类型而且String是不可变的(并且至少被认为是线程安全的).如果两个不同的线程试图在完全相同的时刻在成员变量中存储新字符串,它可能会爆炸.
  3. 是的,不再.如果DAO没有内部状态,是的,我会说它是线程安全的,但它正在处理的对象可能不是(尽管如果你使用JPA实体,它们应该是).
  4. 至少Hibernate的文档说EntityManagers不是线程安全的,但是当使用Spring注入的EntityManager时,它应该不是问题.

SpringSource论坛: 我一直在论坛上寻找相同问题的答案......一般的共识似乎是,虽然每个JPA规范的EntityManager都不是线程安全的,但Spring通过其EntityManager代理注入的EntityManager可能是.

Hibernate: EntityManager是一个廉价的非线程安全对象,应该只使用一次,用于单个业务流程,单个工作单元,然后丢弃.除非需要,否则EntityManager将不会获取JDBC连接(或数据源),因此即使您不确定是否需要数据访问来提供特定请求,您也可以安全地打开和关闭EntityManager.