2010-12-11 60 views
2

我正在爲GlassFish 2.1.1(JavaEE 5,JPA 1.0,據我所知)編寫一些應用程序。我有我的servlet下面的代碼(我主要是從一些樣本借用互聯網上):EntityManager沒有看到其他交易中所做的更改

@PersistenceContext(name = "persistence/em", unitName = "pu") 
private EntityManager em; 

@Resource 
private UserTransaction utx; 

@Override 
protected void doPost(...) { 
    utx.begin(); 
    . . . perform retrieving operations on em . . . 
    utx.rollback(); 
} 

web.xml中有以下內容:

<persistence-context-ref> 
    <persistence-context-ref-name>persistence/em</persistence-context-ref-name> 
    <persistence-unit-name>pu</persistence-unit-name> 
</persistence-context-ref> 

的問題是,在EM沒有按」不會看到在另一個外部交易中所做的更改。粗略地說,我從Web瀏覽器向我的servlet發出請求,查看數據,在SQL控制檯中執行一些DML,重新載入servlet頁面 - 並且不顯示任何更改。我試過使用em.flush,utx.rollbackem.joinTransaction的許多組合,但它似乎沒有任何好處。

由於我是JPA的總新手,情況很複雜,所以我不清楚底層機器是如何工作的。因此,任何幫助和 - 更重要的是 - 對那裏發生的事情的解釋/鏈接都將非常感激。謝謝!

回答

2

JPA實現維護已訪問實體的緩存。當您在不使用JPA的其他事務中執行操作時,緩存不再是最新的,因此您從不會看到其中所做的更改。

如果您確實希望看到更改,則必須刷新緩存,在這種情況下,所有實體都將從緩存中逐出。當然,你需要知道什麼時候這樣做(在其他事務完成之後),否則你將繼續看到不明確的實體。如果這是您的業務需求,那麼JPA可能不適合您的問題域。

相關:

  1. Are entities cached in jpa by default ?
  2. Invalidating JPA EntityManager session
+0

「當你不使用JPA執行不同的事務操作,緩存也不再是最新的」 - 這是否意味着我曾使用過JPA修改上述案例中的數據(而不是一些外部工具),我會在重新加載servlet頁面後看到更改嗎? – 2010-12-11 17:21:57

+0

@安迪,是的,你會的。 EntityManager實際上負責維護緩存。您可能會發現OpenEJB中的JPA概念指南 - http://openejb.apache.org/3.0/jpa-concepts.html非常有用。 – 2010-12-12 20:31:31

0

也許你需要提交在SQL控制檯中進行的事務。

1

由於axtavt說,你需要在控制檯提交事務。假設你這樣做了,那麼PersistenceManager(或底層基礎結構)仍然可能會緩存數據。

爲了防止緩存的麻煩,您可以手動驅逐(這可能比較棘手(因爲您必須知道何時驅逐),或者您可以進行悲觀鎖定。悲觀鎖定可能會對性能產生巨大影響,但是如果您有多個到數據庫的獨立連接,則可能沒有選擇。

如果您的進程在整個過程中都有來自不同源的併發讀/寫操作,那麼您可能確實需要悲觀鎖。如果您有時會從外部源獲得批量更新,那麼您可能會嘗試從該批處理作業發出應該驅逐的JPA應用程序的信號。也許通過Web服務等等。這樣你就不會在整個時間內產生悲觀的鎖定性能下降。

這裏聰明的教訓是流程,同步可以很複雜:)

相關問題