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

时间:2011-02-25 04:45:23

标签: spring jpa jpa-2.0

基于这个例子:

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

  @Autowired
  private PurchaseDAO dao;

  private String normalField;

  .... // methods, operations, etc
}

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

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

1 个答案:

答案 0 :(得分:8)

  1. 默认情况下它们是单例(当它们是Spring管理的时候),除非你已经配置了它们(从xml配置或注释中你可以用@Scope设置它)。
  2. 是和否。是的,在多个线程可以同时访问和修改它的意义上它是不安全的,不是因为它取决于数据类型而且String是不可变的(至少说是线程安全的)。如果两个不同的线程试图在同一时刻在成员变量中存储一个新字符串,它可能会爆炸。
  3. 是的,不再。如果DAO没有内部状态,是的,我会说它是线程安全的,但它正在处理的对象可能不是(尽管如果你使用JPA实体,它们应该是)。
  4. 至少Hibernate的文档说EntityManagers不是线程安全的,但是当使用Spring注入的EntityManager时,它应该不是问题。
  5. SpringSource forums: 我一直在寻找论坛上相同问题的答案......一般的共识似乎是,虽然每个JPA规范的EntityManager都不是线程安全的,但Spring通过其EntityManager代理注入的EntityManager可能是。

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