2012-12-01 40 views
2

我剛剛開始使用AppEngine,但在數據存儲中遇到了一些問題。Appengine和JPA - 讀取剛剛寫入的數據

我想使用JPA將一些數據寫入數據存儲。我一直在使用留言板示例來關注Appengine網站上的Java示例,並且我想將此留言簿示例翻譯爲使用JPA 2.0。

當我在我的輸出中運行具有我的數據存儲中已有的一些數據(使用先前運行創建的)的應用程序時,它顯示我在寫入前有7個項目,然後寫入就可以,之後再次給我7項。但是,如果我打開我的管理控制檯(http:// localhost:8888/_ah/admin/datastore?kind = Greeting),我可以看到數據存儲區中已有8個項目。所以出於某種原因,我正在遭受幻像讀取......

我所有的代碼如下所示。

有沒有人有想法我做錯了什麼?

這是我的persistence.xml看起來像: http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd」版本= 「1.0」>

<persistence-unit name="transactions-optional"> 
    <provider>org.datanucleus.api.jpa.PersistenceProviderImpl</provider> 
    <properties> 
     <property name="datanucleus.NontransactionalRead" value="true"/> 
     <property name="datanucleus.NontransactionalWrite" value="true"/> 
     <property name="datanucleus.ConnectionURL" value="appengine"/> 
    </properties> 
</persistence-unit> 

這是代碼:

 EntityManagerFactory emf = EMF.get(); 
     EntityManager em = emf.createEntityManager(); 
     try { 
      em.getTransaction().begin(); 

      // Reading the data 
      javax.persistence.Query query = em.createQuery("SELECT FROM Greeting g"); 
      List<Greeting> greetings = query.getResultList(); 
      for (Greeting g : greetings) { 
       log.info("Greeting found: " + g.getContent()); 
      } 
      log.info("Number of greetings found before writing: " + greetings.size()); 

      // Storing the data 
      Greeting greeting = new Greeting(); 
      greeting.setUser(user); 
      greeting.setDate(new Date()); 
      greeting.setContent(content); 

      em.persist(greeting); 
      em.flush(); 

      // Reading the data 
      query = em.createQuery("SELECT FROM Greeting g"); 
      greetings = query.getResultList(); 
      for (Greeting g : greetings) { 
       log.info("Greeting found: " + g.getContent()); 
      } 
      log.info("Number of greetings found after writing: " + greetings.size()); 
      em.getTransaction().commit(); 
     } catch (Exception e) { 
      log.warning("Cannot write to database because of error: " + e.getMessage()); 
      e.printStackTrace(); 
     } finally { 
      em.close(); 
      emf.close(); 
     } 

回答

0

谷歌AppEngine上不支持那種數據庫的一致性,而不是在後臺複製數據庫,爲每一位w ^儀式,他們同時寫入> 50%的副本,並在稍後完成複製。所以,如果你寫,然後立即閱讀,你的閱讀可能會擊中尚未複製的副本。

你只需要改變你的代碼,以避免寫後讀。通常這不應該是一個問題,因爲它已經在內存中。

https://developers.google.com/appengine/docs/java/datastore/structuring_for_strong_consistency

要更改設置在Eclipse中,轉到項目>右鍵點擊>谷歌> AppEngine上設置>運行配置> Web應用程序>您的項目>的App Engine>高複製設置(HRD)未覈銷工作百分比> 50.此值模擬在寫入開發之後讀取失敗的百分比。 0%=正常數據庫(但會在生產中失敗)。

JPA位於Datastore API之上,因此它遭受同樣的問題。