2011-02-25 51 views
5

Spring:@PersistenceContext和@Autowired線程安全?基於這個例子

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

    @Autowired 
    private PurchaseDAO dao; 

    private String normalField; 

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

請幫助糾正我,如果即時通訊錯誤的:

  1. 服務類購買PurchaseDAO是由Spring管理的單身
  2. 的服務類的字段normalField不是線程安全的,因爲單例是由許多共享的單個對象
  3. 讓我們假設@庫註解 - PurchaseDAO可是沒有任何領域,這意味着它的線程安全的,將被彈簧自動注入
  4. 的EntityManager實例也是一個線程安全的屬性,因爲@PersistenceContext將使確保當前事務的entityManager將被使用。

謝謝!

+0

hey @bertie,我正在使用'@ PersistenceContext'方法。但它似乎造成了內存泄漏。因爲會議不明確。你有沒有經歷過這樣的事情? – oak

+0

@oak:對不起,我不確定自己,因爲我上次玩JPA已經很長時間了。我建議你爲你的問題和環境創建一個新的問題,放置'@ PersistenceContext'等。 – bertie

回答

7
  1. 他們是默認單身(當它們是Spring管理的),除非你讓他們另行配置(無論從XML配置或註解,你可以用@Scope設置)。
  2. 是和否。是的,多線程可以同時訪問和修改它並不安全,因爲它取決於數據類型,並且字符串是不可變的(並且至少可以說是線程安全的)。如果兩個不同的線程試圖在同一時刻在成員變量中存儲新字符串,它可能會炸燬。
  3. 是的,不是。如果DAO沒有內部狀態,是的,我會說它是線程安全的,但它所處理的對象可能不是(儘管如果你使用的是JPA實體,它們應該是)。
  4. 至少Hibernate的文檔說EntityManagers不是線程安全的,但是當使用由Spring注入的EntityManager時,它不應該是一個問題。

SpringSource forums: 我一直在尋找答案,在論壇上同樣的問題...一般concensus似乎是同時的EntityManager不是線程每JPA規範安全,通過它的EntityManager由Spring注入了EntityManager代理可能會。

Hibernate: 一個EntityManager是應該被使用一次,對於單個的業務流程,工作的單個單元,然後被丟棄一種廉價的,非線程對象。除非需要,否則EntityManager將不會獲得JDBC連接(或數據源),所以即使您不確定是否需要數據訪問來提供特定請求,也可以安全地打開和關閉EntityManager。

+0

2。沒有非final類屬性總是使類不是線程安全的?我的意思是,儘管屬性類型(String)是不可變的,但屬性仍可以更改爲指向不同的對象(另一個String實例)。這不會導致班級變得完全不是線程安全的嗎? –

+0

的確如此,雖然它取決於如何訪問,修改和使用成員變量(類屬性),但總的來說,我會說如果有可能同時從兩個不同的線程修改相同的變量或訪問一個被另一個修改,這會讓這個類不是線程安全的。通過同步或者只讀取變量(或者在這種情況下,可以在使用之前將String引用或整個字符串複製到類之外的另一個引用),同時訪問不應該導致任何問題,因此類應該是線程安全的。 – esaj